Cod sursa(job #369975)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 29 noiembrie 2009 22:01:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.05 kb
#include <fstream>
#include <vector>
using namespace std;
const int NMAX=100001;
int N,M,PE[NMAX*2],poz[NMAX],niv[NMAX],rmq[20][2*NMAX],log[2*NMAX];
vector<int> G[NMAX];
ifstream fin("lca.in");
ofstream fout("lca.out");
void euler(int vf,int k)
{
	PE[++PE[0]]=vf;
	niv[vf]=k;
	vector<int>::iterator it;
	for (it=G[vf].begin();it!=G[vf].end();++it)
	{
		euler(*it,k+1);
		PE[++PE[0]]=vf;
	}
}
int main()
{
	int i,j,k,sol;
    fin>>N>>M;
	for (i=2;i<=N;++i)
	{
		fin>>k;
		G[k].push_back(i);
	}

	euler(1,0);

	for (i=1;i<=PE[0];++i) poz[PE[i]]=i;

	for (i=1;i<=PE[0];++i) rmq[0][i]=PE[i];
	for (i=1;(1<<i)<=PE[0];++i)
	  for (j=1;j+(1<<i)-1<=PE[0];++j)
		  rmq[i][j]= niv[rmq[i-1][j]] < niv[rmq[i-1][j+(1<<(i-1))]] ? rmq[i-1][j] : rmq[i-1][j+(1<<(i-1))];

	log[1]=0;
	for (i=2;i<=PE[0];++i) log[i]=log[i/2]+1;

	while (M--)
	{
		fin>>i>>j;
		i=poz[i];
		j=poz[j];
		if (i>j) swap(i,j);
		k=log[j-i+1];
		sol= niv[rmq[k][i]] < niv[rmq[k][j-(1<<k)+1]] ? rmq[k][i] : rmq[k][j-(1<<k)+1];
		fout<<sol<<'\n';
	}

	return 0;
}