Cod sursa(job #927759)

Utilizator taigi100Cazacu Robert taigi100 Data 26 martie 2013 00:23:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include<stdio.h>
#include<vector>
using namespace std;
#define max 100002
#define maxl 20
int euler[max<<1],nivel[max<<1],prim[max],lg[max<<1],Rmq[maxl][max<<2];
bool vis[max];
vector<int> roads[max];
int n,m,l;
int aux;
void dfs(int node,int lvl)
{
	euler[++l]=node;
	nivel[l]=lvl;
	prim[node]=l;
    for(vector<int>::iterator it=roads[node].begin();it!=roads[node].end();it++)
	{
		dfs(*it,lvl+1);
		euler[++l]=node;
		nivel[l]=lvl;
	}
}

void rmq()
{
	for(int i=2; i<=l; i++)
		lg[i] = lg[i>>1]+1;
	for(int i=1;i<=l;i++)
		Rmq[0][i]=i;

	for(int i=1; (1<<i) < l ; i++)
		for(int j=1;j<=l-(1<<i);j++)
		{
			int q=1<<(i-1);
			Rmq[i][j]=Rmq[i-1][j];
			if(nivel[Rmq[i-1][j+q]]<nivel[Rmq[i][j]])
				Rmq[i][j]=Rmq[i-1][j+q];
		}
}

void lca(int x,int y)
{
	int diff, q,sol,sh;
	int a=prim[x],b=prim[y];
	if(a>b) swap(a,b);
	diff=b-a+1;
	q=lg[diff];
	sol=Rmq[q][a];
	sh=diff-(1<<q);
	if(nivel[sol]>nivel[Rmq[q][a+sh]])
		sol=Rmq[q][a+sh];
	printf("%d\n",euler[sol]);
}
int main()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d %d",&n,&m);
	int a,b;
	for(int i=2;i<=n;i++)
	{
		scanf("%d",&b);
		roads[b].push_back(i);
	}
	dfs(1,0);
	rmq();
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&a,&b);
		lca(a,b);
	}
	return 0;
}