Cod sursa(job #406038)

Utilizator sory1806Sandu Sorina-Gabriela sory1806 Data 1 martie 2010 09:15:04
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.36 kb
#include<stdio.h>
#define nmax 100010
int eu[4*nmax], b[4*nmax][25], c[4*nmax][25], log[nmax], lvl[4*nmax], ap[nmax], n, m, i, lmax;
struct elem
{	int vf;
	elem *nxt;
};
elem *a[nmax], *q;

int min(int x, int y)
{	if(x<y) return x;
	else	return y;
}

void read()
{	int i, x;
	scanf("%d%d", &n, &m);
	for(i=2; i<=n; i++)
	{	scanf("%d", &x);
		q=new elem;
		q->vf=i;
		q->nxt=a[x];
		a[x]=q;
	}
}

void df(int z, int k)
{	elem *q;
	q=a[z];
	i++; eu[i]=z;
	lvl[i]=k; ap[z]=i;
	while(q)
	{	df(q->vf, k+1);
		q=q->nxt;
		i++; eu[i]=z; lvl[i]=k;
	}	
}

void create ()
{	int i, j;
	for(i=0; i<lmax; i++)
	{	b[i][0]=lvl[i+1];
		c[i][0]=eu[i+1];
	}
	for(j=1; (1<<j)<=lmax; j++)
		for(i=0; i+(1<<j)<=lmax; i++)
		{	if((b[i][j-1]<b[i+(1<<(j-1))][j-1]))
			{	b[i][j]=b[i][j-1];
				c[i][j]=c[i][j-1];
			}
			else
			{	b[i][j]=b[i+(1<<(j-1))][j-1];
				c[i][j]=c[i+(1<<(j-1))][j-1];
			}
		}
}


int main()
{	int x, y, k, z;
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	read();
	df(1, 1); lmax=i;
	
	for(i=2; i<=lmax; i++)	log[i]=log[i/2]+1;
	create();
	
	for(i=0; i<m; i++)
	{	scanf("%d%d", &x, &y);
		x=ap[x]-1; y=ap[y]-1;
		if(y<x)
		{	z=x; x=y; y=z;
		}
		k=log[y-x+1];
		if(b[x][k]<b[y+1-(1<<k)][k])
			printf("%d\n", c[x][k]);
		else
			printf("%d\n", c[y+1-(1<<k)][k]);		
	}
	
	return 0;
	
}