Cod sursa(job #447858)

Utilizator alexeiIacob Radu alexei Data 1 mai 2010 15:50:28
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include<stdio.h>
#include<vector>
#define NMAX 100064
#define inf 0x3f3f3f3f
using namespace std;

//Atestat Work//
//intended to get 70pts//

vector< int >G[NMAX];
bool viz[NMAX];

int E[NMAX<<1],L[NMAX<<1],F[NMAX];

struct{
	int node;
	int level;
} A[NMAX*4+64];
	

int sf;

int pos,v1,v2;
int p1,p2;
int ans1,ans2;

void df( int nod, int level )
{

	E[++sf]=nod;
	L[sf]=level;
	F[nod]=sf;

	int i;
	for(i=0; i<G[nod].size(); ++i)
	{
		int son=G[nod][i];
		if( !viz[ son ] )
		{
			viz[ son ]=1;
			df( son,level+1 );
			
			E[++sf]=nod;
			L[sf]=level;
		}
	}
	
}

void update( int nod, int left, int right )
{
	if( left==right )
	{
		A[nod].node=v1;
		A[nod].level=v2;
		return;
	}
	
	int mij=(left+right)>>1;
	int aux=nod<<1;
	
	if( pos<=mij ) update( aux, left, mij );
	else update( aux+1, mij+1, right );
	
	int leftL=A[aux].level;
	int rightL=A[aux+1].level;
	
	if( leftL<rightL )
	{
		A[nod].level=leftL;
		A[nod].node=A[aux].node;
	}
	else
	{
		A[nod].level=rightL;
		A[nod].node=A[aux+1].node;
	}
}

void query( int nod, int left, int right )
{
	if( left>=p1 && right<=p2 )
	{
		if( ans1>A[nod].level )
		{
			ans1=A[nod].level;
			ans2=A[nod].node;
		}
		return;
	}
	
	if( left>p2 || right<p1 ) return;
	
	int mij=(left+right)>>1;
	int aux=nod<<1;

	query( aux, left, mij );
	query( aux+1, mij+1, right );
}

int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	
	int N,M;
	scanf("%d%d",&N,&M);
	
	int i,father;
	for(i=2; i<=N; ++i)
	{
		scanf("%d",&father);
		G[father].push_back(i);
	}
	
	viz[1]=1;
	df(1,1);//
	
	for(i=1; i<=sf; ++i)
	{
		pos=i; v1=E[i]; v2=L[i];
		update( 1, 1, sf );
	}
	
	while( M-- )
	{
		scanf("%d%d",&p1,&p2);
		p1=F[p1]; p2=F[p2];
		
		if( p1>p2 ){p1^=p2;p2^=p1;p1^=p2;}
		
		ans1=inf;
		ans2=-1;
		query( 1, 1, sf );
		
		printf("%d\n",ans2);
	}
	
	return 0;
}