Cod sursa(job #683339)

Utilizator ciprianfFarcasanu Alexandru Ciprian ciprianf Data 20 februarie 2012 15:27:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define N_MAX 100010
#define FOR(i, v) for(vector<int>::iterator i = v.begin(); i != v.end(); i++)
vector <int> G[N_MAX];


int A[18][2*N_MAX];
int in[N_MAX], out[N_MAX];
int L[N_MAX], log[2*N_MAX];
int n, m;
void df(int x) {
	A[0][++A[0][0] ] = x;
	in[x] = A[0][0];
	FOR(i, G[x]) {
		L[*i] = L[x] + 1;
		df(*i);
		A[0][++A[0][0]] = x;
	}
	out[x] = A[0][0];
}

void precompute() {
	log[1] = 0;
	for(int i = 2; i <= A[0][0]; i++) {
		log[i] = log[i/2] + 1;
	}
	for(int j = 1; (1<<j) <= A[0][0]; j++) {
		for(int i = 1; i + (1<<j) - 1 <= A[0][0]; i++)
			if( L[A[j-1][i]] < L[A[j-1][i+(1<<(j-1))]] ) {
				A[j][i] = A[j-1][i];
			}
			else {
				A[j][i] = A[j-1][i+(1<<(j-1))];
			}
		}
}

int min_int(int a, int b) {
	int d = log[b-a];
	if(L[A[d][a]] < L[A[d][b-(1<<d)+1]]) {
		return A[d][a];
	}
	return A[d][b-(1<<d)+1];
}
int lca(int x, int y) {
	if(in[x] > in[y]) swap(x,y);
	return min_int(in[x], in[y]);
}

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);
	}
	df(1);
	precompute();
	for(int i = 1; i <= m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		printf("%d\n", lca(x, y));
	}
	return 0;
}