Cod sursa(job #700976)
#include <fstream>
#include <vector>
#define NMAX 100005
#define LMAX 20
using namespace std;
vector <int>G[NMAX];
int N,M,k;
int Level[NMAX<<1],Euler[NMAX<<1],First[NMAX],Lg[NMAX<<1];
int RMQ[LMAX][NMAX<<2];
void dfs(int nod, int level){
Euler[++k]=nod;
Level[k]=level;
First[nod]=k;
for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();it++){
dfs(*it,level+1);
Euler[++k]=nod;
Level[k]=level;
}
}
void rmq(){
int i,j;
for(i=2;i<=k;i++)
Lg[i]=Lg[i>>1]+1;
for(i=1;i<=k;i++)
RMQ[0][i]=i;
for(i=1;(1<<i)<k;i++)
for(j=1; j<=k-(1<<i);j++){
RMQ[i][j]=RMQ[i-1][j];
if(Level[RMQ[i-1][j+1]]<Level[RMQ[i][j]])
RMQ[i][j]=RMQ[i-1][j+1];
}
}
int lca(int x, int y){
int a,b,dif,l,s,sol;
a=First[x], b=First[y];
if(a>b) swap(a,b);
dif=b-a+1;
l=Lg[dif];
sol=RMQ[l][a];
s=dif-(1<<l);
if(Level[sol]>Level[RMQ[l][a+s]])
sol=RMQ[l][a+s];
return Euler[sol];
}
int main(){
int i,x,y;
ifstream in("lca.in");
ofstream out("lca.out");
in>>N>>M;
for(i=2;i<=N;i++){
in>>x;
G[x].push_back(i);
}
dfs(1,0);
rmq();
for(;M>0;M--){
in>>x>>y;
out<<lca(x,y)<<"\n";
}
in.close();
out.close();
return 0;
}