Cod sursa(job #819575)

Utilizator roots4Irimia Alexandru Gabriel roots4 Data 19 noiembrie 2012 12:43:58
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include<fstream>
#include<vector>
#define DIM 100010
#define p_max 30
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");


vector<int>V[DIM];

int n,m,i,j,a,b,k,nr,aux,sol,lungime;
int A[2*DIM];
int Niv[p_max][2*DIM];
int Rmq[p_max][2*DIM];
int First[DIM];
int P[DIM];

void read(){
	f>>n>>m;
	for(i=1;i<=n-1;i++){
		f>>nr;
		V[nr].push_back(i+1);
	}
}

void dfs(int x,int niv){
	A[++k]=x;
	Niv[0][k]=niv;
	if(First[x]==0)
		First[x]=k;
	
	for(int i=0;i<V[x].size();i++){
		dfs(V[x][i],niv+1);
		A[++k]=x;
		Niv[0][k]=niv;
	}
	
}

void rmq(){
	for(i=1;i<=k;i++)
		Rmq[0][i]=i;
	
	for(j=1;(1<<j)<=k;j++){
		for(i=1;i+(1<<j)-1<=k;i++){
			Rmq[j][i]=Rmq[j-1][i];
			Niv[j][i]=Niv[j-1][i];
			if(Niv[j-1][i+(1<<(j-1))]<Niv[j][i]){
				Rmq[j][i]=Rmq[j-1][i+(1<<(j-1))];
				Niv[j][i]=Niv[j-1][i+(1<<(j-1))];
			}
		}
	}
	
	for(i=2;i<=k;i++)
		P[i]=1+P[i/2];
	
}

void querry(){
	
	for(i=1;i<=m;i++){
		f>>a>>b;
		a=First[a];
		b=First[b];
		if(a>b){
			aux=a;
			a=b;
			b=aux;
		}
		lungime=P[b-a+1];
		
		sol=A[Rmq[lungime][a]];
		
		if(Niv[lungime][b-(1<<lungime)+1]<Niv[lungime][a])
			sol=A[Rmq[lungime][b-(1<<lungime)+1]];
		
		g<<sol<<"\n";
	}
	
}


int main(){
	
	read();
	
	dfs(1,0);
	
	rmq();
	
	querry();
	
	return 0;
}