Cod sursa(job #389580)

Utilizator ciprianfFarcasanu Alexandru Ciprian ciprianf Data 1 februarie 2010 20:59:51
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define NMAX 100010
#define FOR(i, v) for(vector<int>::iterator i = v.begin(); i != v.end(); ++i)
vector <int> G[NMAX];
int R[2*NMAX][18], P[NMAX], D[NMAX], LG[2*NMAX];
int n, m, c;
inline int min(int x, int y){
	if(D[x] > D[y]) return y;
	return x;
}
void agat(int x){
	R[++c][0] = x;
	P[x] = c;
	FOR(i, G[x]){
			D[*i] = D[x] + 1;
			agat(*i);
			R[++c][0] = x;
		}
}
void logaritm(){
	LG[1] = 0;
	for(int i = 2; i <= c; ++i)
		LG[i] = LG[i/2] + 1;
}
void solve(){
	logaritm();
	int log = LG[c];
	for(int j = 1; j <= log; ++j)
		for(int i = 1; i <= c - (1<<j) + 1; ++i)
			R[i][j] = min(R[i][j-1], R[i+(1<<(j-1))][j-1]);
			/*if(D[R[i][j-1]] < D[R[i+(1<<(j-1))][j-1]])
				R[i][j] = R[i][j-1];
			else R[i][j] = R[i+(1<<(j-1))][j-1];*/
}
inline int abs(int x){
	if( x > 0) return x;
	return -x;
}
void swap(int &x, int &y){
	int z = x; x = y; y = z;
}
inline int query(int x,int y){
	if(x > y) swap (x, y);
	int log = LG[y - x + 1];
	return min(R[x][log], R[y - (1<<log) + 1][log]);
}
int main(){
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	scanf("%d%d", &n, &m);
	int x;
	for(int i = 2; i <= n; ++i){
		scanf("%d", &x);
		G[x].push_back(i);
	}
	agat(1);
	solve();
	for(int i = 1; i <= m; ++i){
		int x, y, log;
		scanf("%d%d", &x, &y);
		printf("%d\n",query(P[x], P[y]));
	}
	return 0;
}