Cod sursa(job #569667)

Utilizator b_polarAgape Mihai b_polar Data 1 aprilie 2011 22:36:44
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include <fstream>
#include <cstdio>
#include <vector>
#include <iostream>

using namespace std;
const int NMAX=100001,DMAX=2*NMAX,LOG=18;

ifstream fin("lca.in");
FILE *fout=fopen("lca.out","w");

vector< vector<int> > t(NMAX);
vector< vector<int> > sMin(DMAX,vector<int>(LOG));
vector< pair<int,int> > euler(DMAX);
vector<int> p(NMAX);
int N,Q,cEuler;

void citire(),rezolvare();

int main()
{
	citire();
	rezolvare();
	return 0;
}

void dfs(int tata,int adancime=0)
{
	euler[++cEuler]=pair<int,int>(tata,adancime);
	p[tata]=cEuler;
	for(vector<int>::iterator i=t[tata].begin();i!=t[tata].end();i++)
	{
		dfs(*i,adancime+1);
		euler[++cEuler]=pair<int,int>(tata,adancime);
	}
}

inline int minim(int a,int b)
{
	if(euler[a].second>euler[b].second)
		return b;
	return a;
}

void rezolvare()
{
	dfs(1);
	
	for(int i=1;i<=cEuler;i++)
		sMin[i][0]=i;

	for(int j=1;(1<<j)<=cEuler;j++)
		for(int i=1;i+(1<<j)<=cEuler;i++)
			sMin[i][j]=minim(sMin[i][j-1],sMin[i+(1<<(j-1))][j-1]);

	while(Q--)
	{
		int a,b,k;
		fin>>a>>b;
		a=p[a],b=p[b];
		if(a>b)swap(a,b);
		for(k=17;0==((1<<k)&(b-a+1));--k);
		fprintf(fout,"%d\n",euler[minim(sMin[a][k],sMin[b-(1<<k)+1][k])].first);
	}

	fin.close();
	fclose(fout);
}

void citire()
{
	fin>>N>>Q;
	for(int i=2;i<=N;i++)
	{
		int tata;
		fin>>tata;
		t[tata].push_back(i);
	}
}