Cod sursa(job #432815)

Utilizator NemultumituMatei Ionita Nemultumitu Data 2 aprilie 2010 19:54:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.36 kb
#include <cstdio>
#include <vector>
using namespace std;
vector <int> fii[100010];
int n,m,cnt;
int e[400050],adanc[400050],apar[100100],tat[100100],ad[100100],prep[20][400050];


void dfs(int nod)
{
	e[++cnt]=nod;
	if (!apar[nod])
		apar[nod]=cnt;
	adanc[cnt]=ad[nod];
	for (int i=0;i<fii[nod].size();++i)
	{
		dfs(fii[nod][i]);
		e[++cnt]=nod;
		adanc[cnt]=ad[nod];
	}
}

void citire()
{
	freopen ("lca.in","r",stdin);
	freopen ("lca.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;++i)
	{
		scanf("%d",&tat[i]);
		ad[i]=ad[tat[i]]+1;
		fii[tat[i]].push_back(i);
	}
}

void preprocesare()
{
	for (int i=1;e[i];++i)
		prep[0][i]=i;
	for (int j=1;e[1<<j];++j)
		for (int i=1;e[i+(1<<j)-1];++i)
			if (adanc[prep[j-1][i]]<=adanc[prep[j-1][i+(1<<j-1)]])
				prep[j][i]=prep[j-1][i];
			else
				prep[j][i]=prep[j-1][i+(1<<j-1)];
}

void query()
{
	int st,dr,nod1,nod2;
	while (m--)
	{
		scanf("%d%d",&nod1,&nod2);
		if (apar[nod1]<apar[nod2])
		{
			st=apar[nod1];
			dr=apar[nod2];
		}
		else
		{
			st=apar[nod2];
			dr=apar[nod1];
		}
		int k=0;
		while (1<<k<=dr-st+1)
			++k;
		--k;
		if (adanc[prep[k][st]]<=adanc[prep[k][dr-(1<<k)+1]])
			printf("%d\n",e[prep[k][st]]);
		else
			printf("%d\n",e[prep[k][dr-(1<<k)+1]]);
	}
}

int main()
{
	citire();
	dfs(1);
	preprocesare();
	query();
	return 0;
}