Cod sursa(job #932484)

Utilizator razvan.popaPopa Razvan razvan.popa Data 28 martie 2013 22:51:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include<cstdio>
#include<cmath>
#include<list>
#include<algorithm>
#define pb push_back
#define nxt (*it)
#define FOR(i,a,b)\
   for(int i=a; i<=b; ++i)
#define ALL(g)\
   for(typeof(g.begin()) it=g.begin(); it!=g.end(); ++it)
#define infile "lca.in"
#define outfile "lca.out"
#define nMax 100005
using namespace std;

list < int > v[nMax];

int T[nMax], P[nMax], L[nMax];

int H;

int N, M;


void DFS(int x){
	L[x] = L[T[x]] + 1;

	H = max(H, L[x]);

	ALL(v[x])
	   DFS(nxt);
}

void DF(int x, int up){
	P[x] = up;

	if(L[x] % H == 1)
		up = x;

	ALL(v[x])
	   DF(nxt, up);
}

int lca(int x, int y){
	while(P[x] != P[y])
		if(L[x] > L[y])
			x = P[x];
		else
			y = P[y];

	while(x != y)
		if(L[x] > L[y])
			x = T[x];
		else
			y = T[y];

	return x;
}

int main(){
	freopen(infile, "r", stdin);
	freopen(outfile, "w", stdout);

	scanf("%d %d", &N, &M);

	FOR(x,2,N){
		scanf("%d", &T[x]);

		v[T[x]].pb(x);
	}
    
	DFS(1);

    H = (int) sqrt(double(N)) + 1;

    DF(1, 1);
    
    int x, y;
    while(M--){
    	scanf("%d %d", &x, &y);

    	printf("%d\n", lca(x,y));
    }
    
    fclose(stdin);
    fclose(stdout);

    return 0;
}