Pagini recente » Cod sursa (job #3136043) | Cod sursa (job #2746798) | Cod sursa (job #981737) | Cod sursa (job #2108235) | Cod sursa (job #3265767)
#include<bits/stdc++.h>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX=100001, LGMAX=20;
int n, m, x, y;
int lvl[NMAX], ancestor[LGMAX][NMAX];//al 2^i lea stramos al lui j
vector <int> graph[NMAX];
void dfsLevels(int node)
{
for(int next:graph[node])
{
lvl[next]=lvl[node]+1;
dfsLevels(next);
}
}
void binary_lifting()
{
for(int i=1; i<LGMAX; i++)
for(int j=1; j<=n; j++)
ancestor[i][j] = ancestor[i-1][ancestor[i-1][j]];
}
int XThAncestor(int node, int x)
{
if(x >= (1<<LGMAX))
return 0;
for(int i=0; i<LGMAX; i++)
{
if( x&(1<<i) )//bitul i din x este setat -> sar cu 2^i
node=ancestor[i][node];
}
return node;
}
int lca(int node1,int node2)
{
if(lvl[node1]<lvl[node2])
swap(node1,node2);
node1=XThAncestor(node1, lvl[node1]-lvl[node2] );//ridic nodul 1 la nivelul celuilalt
if(node1==node2)
return node1;
for(int i=LGMAX-1; i>=0; i--)
if(ancestor[i][node1]!=ancestor[i][node2])//al 2^i lea ancestor nu e comun -> sar cu cate 2^i la fiecare
{
node1 = ancestor[i][node1];
node2 = ancestor[i][node2];
}
return ancestor[0][node1];
}
int main()
{
in>>n>>m;
for(int i=2; i<=n; i++)
{
in>>ancestor[0][i];//tatal nodului i
graph[ ancestor[0][i] ].push_back(i);
}
dfsLevels(1);
binary_lifting();
for(int i=1; i<=m; i++)
{
in>>x>>y;
out<<lca(x,y)<<'\n';
}
return 0;
}