Cod sursa(job #1050233)

Utilizator roby2001Sirius roby2001 Data 8 decembrie 2013 13:36:07
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
/*
          ~Keep It Simple!~
*/




#include <stdio.h>
#include <list>

using namespace std;

#define maxn 100001
#define maxl 21
#define min(a,b) a<b ? a:b

int E[2*maxn],F[maxn],L[2*maxn],Rmq[maxn][maxl],Lg[maxn],n,m,k;

list<int> A[maxn];


void Euler(int node,int level)
{
	E[++k] = node;
	L[k] = level;
	F[node] = k;

	for(list<int>::iterator it = A[node].begin(); it!=A[node].end(); it++)
	{
		Euler(*it,level+1);
		E[++k] = node;
		L[k] = level;
	}
}

int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);

	int x;

	scanf("%d %d",&n,&m);

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


	Euler(1,0);

		for(int i=2; i<=k; i++)
		Lg[i] = Lg[i/2] + 1;

	for(int i=1;i<=k;i++)
		Rmq[i][0] = i;

	for(int j = 1; (1<<j) < k; j++)
		for(int i=1; i  <= k - ( 1<<j ) ; i++)
		{
			if( L[Rmq[i][j-1]] > L[Rmq[ i + ( 1<<(j-1))][j-1]])
				Rmq[i][j] = Rmq[ i + ( 1<<(j-1))][j-1];
			else
				Rmq[i][j] = Rmq[i][j-1];
		}

	int y;

	for(int i=1; i<=m; i++)
	{
		scanf("%d %d",&x,&y);
		x = F[x];
		y = F[y];
		if ( x > y ) { int aux = x; x=y; y = aux; }
		int k = Lg[ y-x+1 ];
		if( L[Rmq[x][k]] <= L[Rmq[y - (1<<k)+ 1][k]])
		printf("%d\n",E[Rmq[x][k]]);
		else
			printf("%d\n",E[Rmq[y-(1<<k)+1][k]]);

	}
}