Cod sursa(job #397063)

Utilizator mihaimoldovanMihai Moldovan mihaimoldovan Data 16 februarie 2010 12:26:53
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include<fstream>
#include<vector>
using namespace std;
#define nn 100005
#define nm 20
int n,m,k;
int rmq[nm][nn],lg[nn],h[nn],l[nn],prima[nn];
vector <int> g[nn];//un vector cu elemente tip vector(matrice cu nn linii)
void dfs(int nod,int grad)
{
	h[++k]=nod;
	l[k]=grad;//un heap
	prima[nod]=k;
	for(typeof (g[nod]).begin() it=g[nod].begin();it!=g[nod].end();++it)
	{
		dfs(*it,grad+1);
		h[++k]=nod;
		l[k]=grad;
	}
}
void rrmq()
{
	int i,j;
	for(i=2;i<=k;++i)
		lg[i]=lg[i>>1]+1;
	for(i=i;i<=k;++i)
		rmq[0][i]=i;
	for(i=1;(1<<i)<k;++i)
		for(j=1;j<=k-(1<<i);++j)
		{
			int p=p<<(i-p);
			rmq[i][j]=rmq[i-p][j];
			if(l[rmq[i-p][j+p]]<l[rmq[i][j]])
				rmq[i][j]=rmq[i-1][j+1];
		}
}
int lca(int x,int y)
{
	int diff,p,sol,sh;
    int a = prima[x], b = prima[y];
    if(a > b)
    {
		int aux=a;
		a=b;
		b=aux;
	}
    diff = b - a + 1;
    p = lg[diff];
    sol = rmq[p][a];
    sh = diff - (1 << p);
    if(l[sol]>l[rmq[p][a + sh]])
        sol = rmq[p][a + sh];
    return h[sol];
}
int main()
{
	int a,b,i;
	ifstream fin("lca.in");
	fin>>n>>m;
	for(i=2;i<=n;++i)
	{
		int x;
		fin>>x;
		g[x].push_back(i);
	}
	dfs(1,0);
	rrmq();
	FILE *f=fopen("lca.out","w");
	for(;m;--m)
	{
		fin>>a>>b;
		fprintf(f,"%d\n",lca(a,b));
	}
	fin.close();
	fclose(f);
	return 0;
}