Cod sursa(job #779628)

Utilizator crushackPopescu Silviu crushack Data 18 august 2012 13:36:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.14 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMax 100010
#define LogNMax 19
using namespace std;

const char IN[]="lca.in",OUT[]="lca.out";

int N,M,L;
int v[2*NMax],h[2*NMax],hh[NMax],lg[2*NMax],rmq[LogNMax][2*NMax],Max[NMax],Min[NMax];
vector<int> ad[NMax];

void dfs(int x,int lv=1){
	static int time;
	Min[x]=++time;v[time]=x;h[time]=lv;hh[x]=lv;
	for (int i=0;i<(int)ad[x].size();++i)
	{
		dfs(ad[x][i],lv+1);
		v[++time]=x;h[time]=lv;
	}
	Max[x]=time;
}

int min(int x,int y){
	return hh[x]<hh[y] ? x : y;
}

int main()
{
	int i,j,x,y;
	freopen(IN,"r",stdin);
	scanf("%d%d",&N,&M);
	for (i=2;i<=N;++i)
		scanf("%d",&x),ad[x].push_back(i);

	dfs(1);L=2*N-1;
	lg[1]=0;
	for (i=2;i<=L;++i) lg[i]=lg[i/2]+1;

	for (i=1;i<=L;++i) rmq[0][i]=v[i];

	for (i=1;i<=lg[L];++i)
		for (j=1;j<=L;++j)
			rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<i-1)]);

	freopen(OUT,"w",stdout);
	while (M--)
	{
		scanf("%d%d",&x,&y);
		if (Min[x]>Min[y]) swap(x,y);
		x=Min[x];y=Min[y];
		int m=lg[y-x+1];
		printf("%d\n",min(rmq[m][x],rmq[m][y-(1<<m)+1]));
	}
	fclose(stdout);
	fclose(stdin);
	return 0;
}