Cod sursa(job #478591)

Utilizator razvi9Jurca Razvan razvi9 Data 19 august 2010 12:22:28
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.07 kb
#include <iostream>
#include <vector>
using namespace std;

int n, m, i, j, k, N;
int t[100100][20];
int l[100100];
vector<int> v[100100];

inline int lca(int, int);
void df(int, int);

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

	cin >> n >> m;
	for(i=2;i<=n;++i)
	{
		cin >> t[i][0];
		v[t[i][0]].push_back(i);
	}
	df(1, 0);

	for(i=1, N=0; i <= n; i <<= 1, ++ N);
	for(j=1;j<N;++j)
		for(i=2;i<=n;++i)
			t[i][j] = t[t[i][j-1]][j-1];

	for(;m;--m)
	{
		cin >> i >> j;
		cout << lca(i, j) << endl;
	}
	
	return 0;
}

void df(int n, int lvl)
{
	l[n] = lvl;
	for(int i=0;i<v[n].size();++i)
		df(v[n][i], lvl + 1);
}

int T(int x, int l)
{
	for(int i=1, j=0; i<=l; ++ j, i <<= 1)
		if(l & i)
			x = t[x][j];
	return x;
}

inline int lca(int u, int v)
{
	int lu, lv;
	lu = l[u];
	lv = l[v];

	if(lu > lv)
		u = T(u, lu - lv);
	else
		if(lv > lu)
			v = T(v, lv - lu);

	if(u == v)
		return u;

	for(j=N-1;j>=0;--j)
		if(t[u][j]!=t[v][j])
			u = t[u][j], v = t[v][j];

	return t[u][0];
}