Cod sursa(job #1213583)

Utilizator pulseOvidiu Giorgi pulse Data 28 iulie 2014 15:58:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <cstdio>
#include <vector>
#define nmax 100005

using namespace std;

int K, N, M;
int L[nmax << 1], E[nmax << 1], Lg[nmax << 1], First[nmax];
int rmq[20][nmax << 1];
vector <int> G[nmax];

void dfs(int node, int lev)
{
	E[++K] = node;
	L[K] = lev;
	First[node] = K;
	for (vector <int> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
	{
		dfs(*it, lev + 1);
		E[++K] = node;
		L[K] = lev;
	}
}

void RMQ()
{
	for (int i = 2; i <= K; ++i)
		Lg[i] = Lg[i >> 1] + 1;
	for (int i = 1; i <= K; ++i)
		rmq[0][i] = i;
	for (int i = 1; (1 << i) < K; ++i)
	{
		for (int j = 1; j <= K - (1 << i); ++j)
		{
			int l = 1 << (i - 1);
			rmq[i][j] = rmq[i - 1][j];
			if (E[ rmq[i - 1][j + l] ] < E[ rmq[i][j] ])
				rmq[i][j] = rmq[i - 1][j + l];
		}
	}
}

int lca(int x, int y)
{
	int diff, l, sol, sh;
	int a = First[x], b = First[y];
	if (a > b) swap(a, b);
	diff = b - a + 1;
	l = Lg[diff];
	sol = rmq[l][a];
	sh = diff - (1 << l);
	if (L[sol] > L[ rmq[l][a + sh] ])
		sol = rmq[l][a + sh];
	return E[sol];
}

int main()
{
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	scanf("%d%d", &N, &M);
	for (int i = 2; i <= N; ++i)
	{
		int x;
		scanf("%d", &x);
		G[x].push_back(i);
	}
	dfs(1, 0);
	RMQ();
	for (; M; --M)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		printf("%d\n", lca(x, y));
	}
	return 0;
}