Pagini recente » Cod sursa (job #1894584) | Cod sursa (job #1283191) | Cod sursa (job #74980) | Cod sursa (job #379488) | Cod sursa (job #631196)
Cod sursa(job #631196)
#include <cstdio>
#include <vector>
using namespace std;
const int N=100001;
struct punct{
int val,poz;
}euler[18][2*N];
bool viz[N];
int n,m,nreu,pozeu[N],lg[2*N];
vector <int> edge[N];
void ReadTree(){
int i,x;
freopen("lca.in","r",stdin);
scanf("%d%d",&n,&m);
for(i=2;i<=n;++i){
scanf("%d",&x);
edge[x].push_back(i);
}
}
void DFS(int x,int niv){
int y,i;
viz[x]=true;
pozeu[x]=nreu+1;
for(i=0;i<edge[x].size();++i){
euler[0][++nreu].val=niv;
euler[0][nreu].poz=x;
if(!viz[edge[x][i]]){
DFS(edge[x][i],niv+1);
}
}
euler[0][++nreu].val=niv;
euler[0][nreu].poz=x;
}
void EulerRep(){
DFS(1,0);
}
inline punct min(punct a,punct b){
return a.val<b.val? a : b;
}
void RMQ(){
int i=1,x,y,j,dif,l;
punct aux;
lg[1]=0;
for(i=2;i<=nreu;i++){
lg[i]=lg[i/2]+1;
}
for(i=1;(1<<i)<=nreu;i++){
for(j=1;j<=nreu-(1<<i)+1;j++){
euler[i][j]=min(euler[i-1][j],euler[i-1][j+(1<<i-1)]);
}
}
freopen("lca.out","w",stdout);
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
x=pozeu[x];
y=pozeu[y];
if(y<x){
x^=y;
y^=x;
x^=y;
}
dif=y-x+1;
l=lg[dif];
aux=min(euler[l][x],euler[l][y+1-(1<<l)]);
printf("%d\n",aux.poz);
}
}
int main(){
ReadTree();
EulerRep();
RMQ();
return 0;
}