Cod sursa(job #631193)

Utilizator vlad.doruIon Vlad-Doru vlad.doru Data 7 noiembrie 2011 11:44:47
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 kb
#include <cstdio>
#include <vector>

using namespace std;

const int N=100001;

struct punct{
	int val,poz;
}euler[18][2*N];

int n,m,nreu,pozeu[N],lg[2*N];
vector <int> edge[N];

void ReadTree(){
	int i,x;
	freopen("lca.in","r",stdin);
	scanf("%d%d",&n,&m);
	for(i=2;i<=n;++i){
		scanf("%d",&x);
		edge[x].push_back(i);
	}
}

void DFS(int x,int niv){
	int y,i;
	pozeu[x]=nreu+1;
	for(i=0;i<edge[x].size();++i){
		euler[0][++nreu].val=niv;
		euler[0][nreu].poz=x;
		DFS(edge[x][i],niv+1);
	}
	euler[0][++nreu].val=niv;
	euler[0][nreu].poz=x;
}

void EulerRep(){
	DFS(1,0);
}

inline punct min(punct a,punct b){
	return a.val<b.val? a : b;
}

void RMQ(){
	int i=1,x,y,j,dif,l;
	punct aux;
	lg[1]=0;
	for(i=2;i<=nreu;i++){
		lg[i]=lg[i/2]+1;
	}
	for(i=1;(1<<i)<=nreu;i++){
		for(j=1;j<=nreu-(1<<i)+1;j++){
			euler[i][j]=min(euler[i-1][j],euler[i-1][j+(1<<i-1)]);
		}
	}
	freopen("lca.out","w",stdout);
	for(i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		x=pozeu[x];
		y=pozeu[y];
		if(y<x){
			x^=y;
			y^=x;
			x^=y;
		}
		dif=y-x+1;
		l=lg[dif];
		aux=min(euler[l][x],euler[l][y+1-(1<<l)]);
		printf("%d\n",aux.poz);
	}
}

int main(){
	ReadTree();
	EulerRep();
	RMQ();
	return 0;
}