Cod sursa(job #385553)

Utilizator ConsstantinTabacu Raul Consstantin Data 22 ianuarie 2010 22:33:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.04 kb
#include<stdio.h>
#include<vector>
using namespace std;
#define dim 100005

vector<int>v[dim];

int lvl[ dim ],first[ dim ],rmq[25][dim << 2],i,j,k,m,n,a,b;

void dfs(int nod){
int n,i,x;
n = v[nod].size();
k++;
rmq[0][k] = nod;
first[nod] = k; 

for(i = 0 ; i < n ; i++)
	{x = v[nod][i];
	lvl[x] = lvl[nod] + 1;
	dfs(x);
	k++;
	rmq[0][k] = nod;
	}
}


int min(int a,int b){
if(lvl[a] < lvl[b])
	return a;
return b;
}

int querry(int a,int b){
int m,x,k=1,dif;
a = first[a];b = first[b];
if(a>b){m=a;a=b;b=m;}
dif = b-a+1;
while((1<<k)<=dif)k++;
k--;
dif = dif- (1<<k);
x = min(rmq[k][a],rmq[k][a+dif]);
return x;
}
int main(){
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);

scanf("%d %d",&n,&m);

for(i = 2 ; i <= n ; i++)
	{scanf("%d",&a);
	v[a].push_back(i);
	}
	
dfs(1);
for(i = 1; (1<<i) < k ;i++)
	for(j = 1;j  <= k- (1<<i) ; j++)
		rmq[i][j] = min(rmq[i-1][j],rmq[i-1][j+(1<<i-1)]);

for(i = 1; i <= m ; i++)
	{scanf("%d %d",&a,&b);
	printf("%d\n",querry(a,b));}
return 0;}