Cod sursa(job #640107)

Utilizator ContraPunctContrapunct ContraPunct Data 24 noiembrie 2011 19:45:58
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include<fstream>
#include<vector>

using namespace std;

const int Nmax = 100005;

ifstream in("lca.in");
ofstream out("lca.out");

int lca[Nmax];
vector<int> G[Nmax];
int Euler[Nmax];
int Level[Nmax];
int First[Nmax];
int k;
int n,m;

const int NMAX = 100002;

long int rmq[20][NMAX];
long int ul;
long int lg[NMAX];

void ReadData()
{
	in>>n>>m;
	int i; 
	int x;
	for( i=2;i<=n;++i)
	{
		in>>x;
		G[x].push_back(i);
	}
}
void DFS(int node, int nivel)
{
	vector<int>::iterator i;
	//pun parintele in vector;
	// k e de la 1;
	Level [++k] = nivel;
	First [node] = k;
	Euler [k ] = node;
	
	for(i = G[node].begin(); i!=G[node].end();++i)
	{
		DFS(*i,nivel+1);
		Level [++k] = nivel;
		Euler[k] = node;
	}
}
inline long int min(long int a, long int b)
{
if(a<b)
	return a;
return b;
}
void RMQ()
{
	int i;
	rmq[0][1]=Euler[1];
	
	for (i=2;i<k;i++)
	{
		rmq[0][i]=Euler[i];
		lg[i]=lg[i>>1]+1;
	}
	int j,l;
	for (i=1;(1<<i) <k;i++)
	{
		long int aa = k-(1<<i);
		l=1<<((i-1));
		
		for (j=1;j <= aa;j++)
		{		
		if(rmq[i-1][j] < rmq[i-1][j+l])
			rmq[i][j]= rmq[i-1][j];
		else 
			rmq[i][j]= rmq[i-1][j+l];
		}
	}
	
	
}
void LCA()
{
	long int x,y,diff,sh,l;
	int i;
	for (i=1;i<=m;i++)
	{
		in>>x>>y;
		x=First[x]; y= First[y];
		if( x > y)
			swap(x,y);
		diff=y-x+1;
		l=lg[diff];
		sh=diff - (1<<l);
		diff = min(rmq[l][x],rmq[l][x+sh]);
		out<<diff<<"\n";
	}	
}
int main()
{
	ReadData();
	DFS(1,0);
	RMQ();
	LCA();
	return 0;
}