Pagini recente » Cod sursa (job #2923742) | Cod sursa (job #1689977) | Cod sursa (job #2686858) | Cod sursa (job #3012) | Cod sursa (job #3193949)
#include<bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int NMAX=100005,LOGMAX=20;
int n,m,x,y,level[NMAX],ancestor[LOGMAX][NMAX];
/// ancestor[i][j] = the 2^i ancestor of j
vector<int>graph[NMAX];
void dfs(int node)
{
for(int next:graph[node])
{
level[next]=level[node]+1;
dfs(next);
}
}
void binary_lifting()
{
for(int i=1; i<LOGMAX; i++)
for(int j=1; j<=n; j++)
ancestor[i][j]=ancestor[i-1][ancestor[i-1][j]];
}
int find_ancestor(int node,int no_ancestor)
{
if(no_ancestor>=(1<<LOGMAX))
return 0;
for(int i=0; i<LOGMAX; i++)
if(no_ancestor&(1<<i))
node=ancestor[i][node];
return node;
}
int lca(int node1,int node2)
{
if(level[node1]<level[node2])
swap(node1,node2);
node1=find_ancestor(node1,level[node1]-level[node2]);/// bring the nodes to the same level
if(node1==node2)
return node1;/// node2 is the lca
/// finding the lca otherwise
for(int i=LOGMAX-1; i>=0; i--)
if(ancestor[i][node1]!=ancestor[i][node2])
{
node1=ancestor[i][node1];
node2=ancestor[i][node2];
}
return ancestor[0][node1];/// because node1 and node2 are right under LCA
}
int main()
{
f>>n>>m;
for(int i=2; i<=n; i++)
{
f>>ancestor[0][i];
graph[ancestor[0][i]].push_back(i);
}
level[1]=0;
dfs(1);
binary_lifting();
for(int i=1; i<=m; i++)
{
f>>x>>y;
g<<lca(x,y)<<'\n';
}
return 0;
}