Cod sursa(job #402999)

Utilizator katakunaCazacu Alexandru katakuna Data 24 februarie 2010 14:12:56
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <cstdio>
#include <vector>
using namespace std;

#define Nmax 100010

int n, T, N, niv, k;
int E[Nmax << 1], Niv[Nmax << 1], poz[Nmax << 1], lg[Nmax << 1], rmq[18][Nmax << 1];
vector <int> V[Nmax];

void euler (int nod) {
	
	E[++N] = nod; Niv[N] = niv; poz[nod] = N;
	for (int i = 0; i < (int)V[nod].size (); i++) {
		niv++;
		euler (V[nod][i]);
		niv--; E[++N] = nod; Niv[N] = niv;
	}
}

void Rmq () {
	
	int i; rmq[0][1] = 1;
	for (i = 2; i <= N; i++)
		rmq[0][i] = i, lg[i] = lg[i >> 1] + 1;
	
	for (k = 1; (1 << k) <= N; k++) 
		for (i = 1; i + (1 << k) - 1 <= N; i++) {
			rmq[k][i] = rmq[k-1][i];
			if ( Niv[ rmq[k-1][i + (1 << (k - 1))] ] < Niv[ rmq[k-1][i] ] )
				rmq[k][i] = rmq[k-1][i + (1 << (k - 1))];
		}
}

int main () {

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

	scanf ("%d %d", &n, &T);
	int x;
	for (int i = 2; i <= n; i++) 
		scanf ("%d", &x), V[x].push_back (i);
	
	niv++; euler (1);
	
	Rmq ();
	
	int a, b, aux, k;
	for (; T; T--) {
		scanf ("%d %d", &a, &b);
		a = poz[a]; b = poz[b];
		if (a > b) {aux = a; a = b; b = aux;}
		
		k = lg[b - a + 1];
		if (Niv[ rmq[k][a] ] < Niv[ rmq[k][b - (1 << k) + 1] ])
			printf ("%d\n", E[ rmq[k][a] ]);
		else
			printf ("%d\n", E[ rmq[k][b - (1 << k) + 1] ]);
	}
	
	return 0;
}