Cod sursa(job #411759)

Utilizator socheoSorodoc Ionut socheo Data 5 martie 2010 09:52:19
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;

vector<int>g[100001];
int rmq[21][400002];
int e[200001],l[200001],pr[200001],lg[200001];
int m,n,k;
/*int min(int nr1,int nr2)
{if(nr1<nr2) return nr1;
	 else return nr2;
}
*/
void euler(int nod,int niv)
{ 	e[++k]=nod;
	l[k]=niv;
	pr[nod]=k;
	for(vector<int>::iterator it=g[nod].begin();it!=g[nod].end();it++)
	{	euler(*it,niv+1);
		e[++k]=nod;
		l[k]=niv;
	}
}

void rm()
{ 	for(int i = 2; i <= k; ++i)
		lg[i] = lg[i >> 1] + 1;
	for(int i=1;i<=k;++i)
		rmq[0][i]=i;
	int f=1;
	for(int i=1;(1<<i)<k;++i)
		for(int j=1;j<=k-(1<<i);++j)
				{   f=1<<(i-1);
					rmq[i][j]=rmq[i-1][j];
					if(l[rmq[i-1][j + f]] < l[rmq[i][j]])
						rmq[i][j]=rmq[i-1][j+f];
				}
}

int lca(int x ,int y)
{int nr1=pr[x];
 int nr2=pr[y];
 if(nr1>nr2) swap(nr1,nr2);
 int dif=nr2-nr1+1;
 int r=lg[dif];
 int sol=rmq[r][nr1];
 dif=dif-(1<<r);
 if(l[sol]>l[rmq[r][nr1+dif]])
	 sol=rmq[r][nr1+dif];
 return e[sol];
}

int main()
{	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;++i)
	{	int x;
		scanf("%d",&x);
		g[x].push_back(i);
	}
	euler(1,0);
	rm();
	for(int i=1;i<=m;i++)
	{	int u,o;
		scanf("%d%d",&u,&o);
		printf("%d\n",lca(u,o));
	}
	
	
	return 0;}