Cod sursa(job #1069916)

Utilizator IonMosnoiIon Mosnoi IonMosnoi Data 30 decembrie 2013 17:47:20
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <stdio.h>
#include<vector>
#define pb push_back
#include <math.h> 
using namespace std;
const int  nmax = 108000;

vector < int > a[nmax];

int n,m,E[nmax*2],P[nmax],L[nmax*2],p[20][nmax],H[nmax],in=-1;

void dfs(int nod){
   E[++in] = nod;
   P[in]=L[nod];
   H[nod]=in;
   for(int i=0;i<a[nod].size();i++){
   	dfs(a[nod][i]);
   	if(i!=a[nod].size()-1){
   	E[++in]=nod; //H[nod]=in;	
   	P[in]=L[nod];
   	}
   }
   if(a[nod].size())
   E[++in] = nod, P[in]=L[nod];// H[nod]=in;
}

void create(){	
	
	for(int i =0 ;i<in;i++)p[0][i]=i;
	
	for (int j = 1; 1 << j <= in; j++)
          for (int i = 0; i + (1 << j) - 1 < in; i++)
              if (P[p[j - 1][i]] < P[p[j - 1][i + (1 << (j - 1))]])
                  p[j][i] = p[j - 1][i];
              else
                  p[j][i] = p[j - 1][i + (1 << (j - 1))];
	  
}

int lca(int x,int y){
	x-=1;y-=1;
	int k;// = trunc(log);//log(y-x+1)
	for(k=1; 1<<k<=y-x+1;k++);k--;//return k;
	if(P[p[k][x]]<P[p[k][y-(1<<k)+1]])return p[k][x];
	return p[k][y-(1<<k)+1];
//	return min(P[p[k][x]],P[p[k][y-(1<<k)+1]]);

}

int main(){
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%ld%ld",&n,&m);
int x,y;
L[1]=0;
for(int i=2;i<=n;i++){
scanf("%d",&x);
a[x].pb(i);
L[i] = L[x]+1;
}

dfs(1);
in++;
create();
for(int i=1;i<=m;i++){
	scanf("%d %d",&x,&y);
	printf("%d\n",E[lca(H[x],H[y])]);
}


fclose(stdout); fclose(stdin);
return 0;
}