Pagini recente » Cod sursa (job #2049888) | Cod sursa (job #895157) | Cod sursa (job #1038607) | Cod sursa (job #1566763) | Cod sursa (job #1367409)
#include <bits/stdc++.h>
using namespace std;
const int Nmax = 100000 + 1;
const int LgMax = 18;
vector<int> G[Nmax];
int posEuler[Nmax];
int euler[2 * Nmax];
int level[2 * Nmax];
int LOG[2 * Nmax];
int rmq[LgMax][2 * Nmax];
int N, M, E;
void dfs(int nod, int d)
{
E++;
euler[E] = nod;
level[E] = d;
for (int son: G[nod])
{
dfs(son, d + 1);
E++;
euler[E] = nod;
level[E] = d;
}
}
void build_rmq()
{
for ( int i = 1; i <= E; ++i )
rmq[0][i] = i;
for ( int i = 1; (1 << i) <= E; ++i )
for ( int j = 1; j + (1 << i) - 1 <= E; ++j )
{
int p = 1 << (i - 1);
if ( level[ rmq[i - 1][j] ] < level[ rmq[i - 1][j + p] ] )
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + p];
}
for ( int i = 2; i <= E; ++i )
LOG[i] = LOG[i / 2] + 1;
}
int lca(int x, int y)
{
x = posEuler[x];
y = posEuler[y];
if (x > y)
swap(x, y);
int d = y - x + 1;
int k = LOG[d];
int p = (1 << k);
int sh = d - p;
if ( level[ rmq[k][x] ] < level[ rmq[k][x + sh] ] )
return euler[ rmq[k][x] ];
else
return euler[ rmq[k][x + sh] ];
}
int main()
{
ifstream f("lca.in");
ofstream g("lca.out");
f >> N >> M;
for ( int i = 2, a; i <= N; ++i )
{
f >> a;
G[a].push_back( i );
}
dfs(1, 0);
for ( int i = 1; i <= E; ++i )
{
if ( posEuler[ euler[i] ] == 0 )
{
posEuler[ euler[i] ] = i;
}
}
build_rmq();
for ( int i = 1, a, b; i <= M; ++i )
{
f >> a >> b;
g << lca( a, b ) << "\n";
}
return 0;
}