Cod sursa(job #419327)

Utilizator Andrei_ScorpioAndreiana Andrei Daniel Andrei_Scorpio Data 17 martie 2010 12:12:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include<stdio.h>
#define nmax 100000
int n,m,poz,t[nmax],vec[4*nmax],niv[nmax],ap[nmax],mat[25][4*nmax],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;
		}
	}	
}

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