Cod sursa(job #815218)

Utilizator roots4Irimia Alexandru Gabriel roots4 Data 16 noiembrie 2012 18:32:18
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include<stdio.h>
#include<vector>
#include<string.h>
#define DIM 100010
#define inf 200000000
using namespace std;

vector<int> V[DIM];
int n,m,i,j,Niv[2*DIM][25],A[2*DIM],a,b,k,First[2*DIM],lungime,P[100],Sol[2*DIM][25],sol;
FILE*f=fopen("lca.in","r");
FILE*g=fopen("lca.out","w");

int minim(int a, int b){
	if(a<b)
		return a;
	return b;
}

void read(){
	fscanf(f,"%d%d",&n,&m);
	
	for(int i=2;i<=n;i++){
		fscanf(f,"%d",&a);
		V[a].push_back(i);
	}
	
}

void dfs(int nod,int niv){

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


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

void querry(){
	for(int i=1;i<=m;i++){
		fscanf(f,"%d%d",&a,&b);
		a=First[a];
		b=First[b];
		if(a>b) swap(a,b);
		lungime=b-a+1;
		sol=Sol[a][P[lungime]];
		if(Niv[b-(1<<P[lungime])+1][P[lungime]]<Niv[a][P[lungime]])
			sol=Sol[b-(1<<P[lungime])+1][P[lungime]];
		fprintf(g,"%d\n",sol);
	}
	
}

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