Cod sursa(job #762238)

Utilizator theodora_maneaManea Theodora Maria theodora_manea Data 29 iunie 2012 14:54:44
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define max_n 100005
#define max_l 20

int n,m,k,x,y;
int niv[max_n << 1],E[max_n << 1],Lg[max_n << 1],ap[max_n],Rmq[max_l][max_n << 2];

vector <int> g[max_n];
vector <int>::iterator it;

void citire () {
	for (int i=2; i<=n; ++i) {
		scanf("%d",&x);
		g[x].push_back(i);
	}
}

void DFS(int nod,int nivel) {
	E[++k]=nod;
	niv[k]=nivel;
	ap[nod]=k;
	vector <int>::iterator it;
	for (it=g[nod].begin(); it!=g[nod].end(); it++) {
		DFS(*it, nivel+1);
		
		E[++k]=nod;
		niv[k]=nivel;
	}
}


void RMQ()
{
	for(int i=2; i<=k; ++i)
		Lg[i]=Lg[i >> 1]+1;
	for(int i=1; i<=k; ++i)
		Rmq[0][i]=i;
	
	for(int i=1; (1 << i)<k; ++i)
		for(int j=1; j<=k-(1 << i); ++j)
		{
			int l=1 << (i - 1);
			
			Rmq[i][j]=Rmq[i-1][j];
			if(niv[Rmq[i-1][j + l]]<niv[Rmq[i][j]])
				Rmq[i][j]=Rmq[i-1][j + l];
		}
}		

int LCA(int x, int y) {
	int a,b,dif,q,l,sol;
	a=ap[x];  b=ap[y];
	if (a>b) swap(a,b);
	dif=b-a+1;
	l=Lg[dif];
    sol=Rmq[l][a];
    q=dif-(1 << l);
    if(niv[sol]>niv[Rmq[l][a+q]])
		sol=Rmq[l][a+q];
    return E[sol];
}

int main () {
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&n,&m);
	citire();
	k=0;
	DFS(1,0);
	RMQ();
	for (int i=1; i<=m; i++) {
		scanf("%d%d",&x,&y);
		printf("%d\n",LCA(x,y));
	}
	return 0;
}