Cod sursa(job #478624)

Utilizator mottyMatei-Dan Epure motty Data 19 august 2010 14:45:33
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include<cstdio>
#include<vector>

using namespace std;

const int N=100001, M=21;

int n, m, mn[M][N], eu[N*5], pie, lev[N], u[N];

vector <int> g[N];

void Read()
{
	int par;
	scanf( "%d%d", &n, &m);
	for( int i=2; i<=n; ++i)
	{
		scanf( "%d", &par);
		g[par].push_back(i);
	}
}

void GetLev(int x)
{
	int sz=g[x].size();
	eu[++pie]=x;
	u[x]=pie;
	for( int i=0; i<sz; ++i)
	{
		lev[g[x][i]]=lev[x]+1;
		GetLev(g[x][i]);
		eu[++pie]=x;
	}
}

inline int GetPowMax(int x)
{
	int PowMax=0;
	while( (1<<(PowMax+1))<=x )
		++PowMax;
	return PowMax;
}

int GetMin( int i, int j)
{
	int a, b;
	a=mn[i-1][j];
	b=mn[i-1][ j+(1<<(i-1)) ];
	return (lev[a]<lev[b] ? a:b);
}

void RanMinQr()
{
	for( int i=1; i<=pie; ++i)
		mn[0][i]=eu[i];
	int PowMax=GetPowMax(pie);
	for( int i=1; i<=PowMax; ++i)
		for( int j=1; j<=(pie-(1<<i)+1); ++j)
			mn[i][j]=GetMin( i, j);
}

void GetAwnsers()
{
	int PowMax, a, b, auxa, auxb;
	while(m--)
	{
		scanf( "%d%d", &a, &b);
		a=u[a];
		b=u[b];
		PowMax=GetPowMax(b-a+1);
		auxa=mn[PowMax][a];
		auxb=mn[PowMax][b-(1<<PowMax)+1];
		auxa= (auxa<auxb ? auxa:auxb);
		printf( "%d\n", auxa);
	}
}

int main()
{
	freopen( "lca.in", "r", stdin);
	freopen( "lca.out", "w", stdout);
	
	Read();
	GetLev(1);
	RanMinQr();
	GetAwnsers();
	
	return 0;
}