Pagini recente » Monitorul de evaluare | Cod sursa (job #3354879) | Cod sursa (job #3354491) | Cod sursa (job #354965) | Cod sursa (job #3348733)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int NMAX = 1e5 + 1, LOG = 17;
vector <int> sons[NMAX];
int anc[NMAX][LOG + 1];
int level[NMAX];
void dfs ( int nod, int lvl )
{
level[nod] = lvl + 1;
for ( int i = 1; i < LOG && anc[nod][i - 1]; i ++ )
anc[nod][i] = anc[anc[nod][i - 1]][i - 1];
for ( auto it : sons[nod] )
dfs ( it, lvl + 1 );
}
int ancestor ( int nod, int exp )
{
for ( int i = LOG; i >= 0; i -- )
{
if ( ( 1 << i ) <= exp )
{
exp -= ( 1 << i );
nod = anc[nod][i];
}
}
return nod;
}
void balance_level ( int &a, int &b )
{
if ( level[a] == level[b] )
return;
if ( level[a] < level[b] )
swap ( a, b );
a = ancestor ( a, level[a] - level[b] );
}
int lca ( int a, int b )
{
balance_level ( a, b );
if ( a == b )
return a;
for ( int i = LOG; i >= 0; i -- )
{
if ( anc[a][i] != anc[b][i] )
return lca ( anc[a][i], anc[b][i] );
}
if ( anc[a][0] == anc[b][0] )
return anc[a][0];
else return 0;
}
int main()
{
int n, q;
f >> n >> q;
for ( int i = 2; i <= n; i ++ )
{
int x;
f >> x;
anc[i][0] = x;
sons[x].push_back(i);
}
dfs ( 1, 0 );
while ( q -- )
{
int a, b;
f >> a >> b;
g << lca( a, b ) << '\n';
}
return 0;
}