Cod sursa(job #832102)

Utilizator MtkMarianHagrSnaf MtkMarian Data 9 decembrie 2012 20:54:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include<cstdio>
#include<vector>

using namespace std;

#define NMAX 100006
#define MAXL 20

vector< int > g[NMAX];


int euler[2*NMAX-1];
int deep[2*NMAX-1];
int first[NMAX];
int n,m ,k=0,x,y;
int lg[2*NMAX-1];
int rq[MAXL][2*NMAX-1];



void dfs(int nod,int level)
{
	euler[++k]=nod ;
	deep[ k ]=level ;
	first[nod]=k;

	for(int i=0;i<g[nod].size();++i )
	{
		dfs(g[nod][i],level+1);
		euler[++k]=nod;
		deep[k]=level;
	}



}

void rmq()
{
	int l;
	for( int i=1;i <= k ; ++i )
	{
		rq[0][i]=i;
	
	}


	for(int i=1 ; (1<<i) < k ; ++i)
		for (int j=1 ; j <= k - ( 1<<i ) ; ++j)
		{
			l=1<<(i-1);

			rq[i][j]=rq[i-1][j];
			
			if(deep[ rq[i][j] ] > deep[ rq[i-1][j+l] ])
				rq[i][j]=rq[i-1][j+l];
			
		}

}

int lca(int x,int y)
{
	int pdif,dif,p,a,b,poz;
	a=first[x];
	b=first[y];
	if(a>b)swap(a,b);

	dif=b-a+1;
	p=lg[dif];

	pdif=dif-(1<<p);
	poz=rq[p][a];
	
	
	if(deep[poz]>deep[rq[p][a+pdif]])
		poz=rq[p][a+pdif];
	return euler[poz];

}


void citeste()
{
	scanf("%d %d",&n,&m);
	for(int i=2;i<=n;++i)
	{
		
		scanf( "%d" ,&x );
		g[x].push_back(i);
	}


}

int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
   
	citeste();
	
	deep[1]=0;
	
	dfs(1,0);

	for ( int i=2 ; i <=k ; ++i)
		lg[i]= lg[(i>>1)]+1;




	rmq();

	for(int i=1;i<=m;++i)
	{
		scanf("%d %d",&x,&y);
		printf("%d\n" , lca(x,y) );

	}



	
	return 0;
}