Cod sursa(job #1453665)

Utilizator theprdvtheprdv theprdv Data 24 iunie 2015 06:03:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 kb
/* Time Complexity: O( N * logN + M * logN) */

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define MAXN 100001
#define foreach(V) for(vector <int>::iterator it = (V).begin(); it != (V).end(); ++it)

using namespace std;

int N, M, A[20][MAXN], Lev[MAXN];
vector <int> G[MAXN];

void DFS(int n, int lv){
	Lev[n] = lv;

	foreach(G[n]) DFS(*it, lv + 1);
}

int LCA(int x, int y){
	int i;
	if (Lev[x] > Lev[y])
		while (Lev[x] != Lev[y]){
			for (i = 0; (1 << i) <= Lev[x] - Lev[y]; ++i);
			--i, x = A[i][x];
		}
	else if (Lev[x] < Lev[y])
		while (Lev[x] != Lev[y]){
			for (i = 0; (1 << i) <= Lev[y] - Lev[x]; ++i);
			--i, y = A[i][y];
		}

	while (x != y){
		for (i = 0; A[i][x] != A[i][y]; ++i);
		if (i) --i;
		x = A[i][x], y = A[i][y];
	}
	return x;
}

int main(){
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	
	scanf("%d %d", &N, &M);
	for (int i = 2; i <= N; ++i)
		scanf("%d", &A[0][i]),
		G[A[0][i]].push_back(i);

	DFS(1, 0);
	for (int i = 1; (1 << i) <= N; ++i)
		for (int j = 1; j <= N; ++j)
			A[i][j] = A[i - 1][A[i - 1][j]];
	
	for (int x, y; M; --M)
		scanf("%d %d", &x, &y),
		printf("%d\n", LCA(x, y));

	return 0;
}