Cod sursa(job #485771)

Utilizator antoanelaAntoanela Siminiuc antoanela Data 19 septembrie 2010 14:39:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.13 kb
#include <cstdio>
#include <vector>
using namespace std;
#define nmax 100010

vector <int> v[nmax];
int n, m, l, e[nmax<<1], r[20][nmax<<1], f[nmax<<1], lg[nmax<<1], lev[nmax<<1];

inline void dfs (int nod, int h)
{
	e[++l]=nod;
	lev[l]=h;
	f[nod]=l;
	int i;
	for (i=0; i<v[nod].size(); i++)
	{
		dfs(v[nod][i], h+1);
		e[++l]=nod;
		lev[l]=h;
	}
}

inline void rmq()
{
	int i, j;
	for (i=2; i<=l; i++) lg[i]=lg[i>>1]+1;
	for (i=1; i<=l; i++) r[0][i]=i;
	for (i=1; (1<<i)<l; i++)
		for (j=1; j<=l-(1<<i)+1; j++) 
			if (lev[r[i-1][j]]<lev[r[i-1][j+(1<<(i-1))]])
				r[i][j]=r[i-1][j]; else
				r[i][j]=r[i-1][j+(1<<(i-1))];
}

inline int lca(int x, int y)
{
	int d;
	x=f[x];
	y=f[y];
	if (x>y) swap(x,y);
	d=lg[y-x+1];
	if (lev[r[d][x]]<lev[r[d][y-(1<<d)+1]]) 	
		return e[r[d][x]]; else
		return e[r[d][y-(1<<d)+1]];
}

int main()
{
	freopen ("lca.in","r",stdin);
	freopen ("lca.out","w",stdout);
	scanf("%d %d",&n,&m);
	int i, x, y;
	for (i=2; i<=n; i++)
	{
		scanf("%d",&x);
		v[x].push_back(i);
	}
	dfs(1,1);
	rmq();
	while (m--)
	{
		scanf("%d %d",&x,&y);
		printf("%d\n", lca(x,y));
	}
}