Cod sursa(job #410800)

Utilizator diannaDiaconu Diana dianna Data 4 martie 2010 16:36:46
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include<stdio.h>
#define nmax 100000
int n,m,poz,t[nmax],vec[4*nmax],niv[nmax],ap[nmax],q[4*nmax][22],log[nmax];
struct nod
{
	int inf;
	nod *urm;
}*a[nmax];

void citire()
{
	int x; nod *p;
	freopen("lca.in","r",stdin);
	scanf("%d %d",&n,&m);
	for(int i=2;i<=n;i++)
	{
		scanf("%d",&x);
		t[i]=x;
		p=new nod;
		p->inf=i;
		p->urm=a[x];
		a[x]=p;
	}
}

void parcurg(int k)
{
	nod *p;
	vec[++poz]=k;
	if(ap[k]==0)
		ap[k]=poz;
	if(a[k]!=NULL)
	{
		for(p=a[k];p!=NULL;p=p->urm)
		{	
			niv[p->inf]=niv[k]+1;
			parcurg(p->inf);
			vec[++poz]=k;
		}
	}	
}


void init()
{
	int i,j;
	log[0]=-1;
	for(i=1;i<=poz;i++)
	{
		q[i][0]=vec[i];
		log[i]=log[i>>1]+1;
	}
	for(j=1;j<=log[poz];j++)
		for(int i=1;i+(1<<(j-1))<=poz;i++)
			if(niv[q[i][j-1]]<niv[q[i+(1<<(j-1))][j-1]])
				q[i][j]=q[i][j-1];
			else
				q[i][j]=q[i+(1<<(j-1))][j-1];
}
	
int main()
{
	int x,y,i,j;
	freopen("lca.out","w",stdout);
	citire();
	parcurg(1);
	init();
	for(i=0;i<m;i++)
	{	
		int k;
		scanf("%d%d",&x,&y);
		x=ap[x];
		y=ap[y];
		if(x>y)
		{
			int z=x;
			x=y;
			y=z;
		}
		k=log[y-x+1];
		if(niv[q[x][k]]<niv[q[y-(1<<k)+1][k]])
			printf("%d\n",q[x][k]);
		else
			printf("%d\n",q[y-(1<<k)+1][k]);
	}
	return 0;
}