Cod sursa(job #408860)

Utilizator hasegandaniHasegan Daniel hasegandani Data 3 martie 2010 11:53:53
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include<stdio.h>
#include<vector>

using namespace std;

#define Nmax 100010
#define Emax 500010
#define log 20
int N,t[Nmax],niv[Nmax];
vector <int> l[Nmax];
int E[Emax],Ne[Emax],F[Nmax],Nr;
int Rmq[log][Emax],lg[Emax];

int min(int x,int y)
{return (x<y?x:y);}

int lca(int A,int B)
{
	A=F[A]; B=F[B];
	int C,dist,k,Sol;
	if (A>B)
		C=A, A=B, B=C;
	dist=B-A;
	k=lg[dist];
	Sol=Rmq[k][A];
	if (Ne[ Sol ] > Ne[ Rmq[k][B-(1<<k)] ])
		Sol = Rmq[k][B-(1<<k)];
	
	return (E[Sol]);
}

void rmq()
{
	for(int i=2;i<=Nr;++i)
		lg[i]=lg[i>>1]+1;
	for(int i=1;i<=Nr;++i)
	{
		Rmq[0][i]=i;
		Ne[i]=niv[E[i]];
	}
	
	for(int i=1;(1<<i)<=Nr;++i)
		for(int j=1,p=(1<<(i-1)); j+(1<<i)-1<=Nr ;++j)
		{
			Rmq[i][j]=Rmq[i-1][j];
			if (Ne[ Rmq[i][j] ] > Ne[ Rmq[i-1][j+p] ])
				Rmq[i][j]=Rmq[i-1][j+p];
		}
}

void DF(int k)
{
	E[++Nr]=k;
	F[k]=Nr;
	
	for(int i=0;i<(int)l[k].size();++i)
	{
		niv[ l[k][i] ]=niv[k]+1;
		DF( l[k][i] );
		E[++Nr]=k;
	}
}


int main()
{
	int M,a,b;
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&N,&M);
	for(int i=2;i<=N;++i)
	{
		scanf("%d",&t[i]);
		l[ t[i] ].push_back(i);
	}
	
	DF(1);
	rmq();
	
	for(int i=1;i<=M;++i)
	{
		scanf("%d %d",&a,&b);
		printf("%d\n",lca(a,b));
	}
	return 0;
}