Pagini recente » Cod sursa (job #1422934) | info-arena 2.0 | Cod sursa (job #2876257) | Cod sursa (job #2389311) | Cod sursa (job #1494591)
#include <fstream>
#include <vector>
#include <bitset>
#define INF 0x3f3f3f3f
using namespace std;
ifstream is("lca.in");
ofstream os("lca.out");
using VI = vector<int>;
using VVI = vector<VI>;
int n, m;
VI e, poz, niv, log;
VVI g, r;
void Read();
void Euler(int nod, int k);
void RMQ();
int main()
{
Read();
e.push_back(0);
niv.push_back(0);
poz = VI(n + 1);
Euler(1, 1);
RMQ();
int x, y, val;
while ( m-- )
{
is >> x >> y;
x = poz[x];
y = poz[y];
val = log[y - x + 1];
if ( x > y )
swap(x, y);
if ( niv[r[x][val]] < niv[r[y - ( 1 << val ) + 1 ][val]] )
os << e[r[x][val]] << "\n";
else
os << e[r[y - ( 1 << val ) + 1 ][val]] << "\n";
}
is.close();
os.close();
return 0;
}
void RMQ()
{
log = VI(2 * n);
for ( int i = 2; i < 2 * n; ++i )
log[i] = log[i / 2] + 1;
r = VVI(2 * n, VI(20));
for ( int i = 0; i < 2 * n; ++i )
r[i][0] = i;
for ( int j = 1; ( 1 << j ) < 2 * n; ++j )
for ( int i = 1; i + ( 1 << j ) < 2 * n; ++i )
if ( niv[r[i][j - 1]] < niv[r[i + ( 1 << ( j - 1 ) )][j - 1]] )
r[i][j] = r[i][j - 1];
else
r[i][j] = r[i + ( 1 << ( j - 1 ) )][j - 1];
}
void Euler(int nod, int k)
{
poz[nod] = e.size();
for ( const auto &nodv : g[nod] )
if ( !poz[nodv] )
{
e.push_back(nod);
niv.push_back(k);
Euler(nodv, k + 1);
}
e.push_back(nod);
niv.push_back(k);
}
void Read()
{
int x;
is >> n >> m;
g = VVI(n + 1);
for ( int i = 2; i <= n; ++i )
{
is >> x;
g[x].push_back(i);
}
}