Cod sursa(job #433395)

Utilizator otilia_sOtilia Stretcu otilia_s Data 3 aprilie 2010 17:35:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100004
#define KMAX 230000
#define LOGK 20

int M[LOGK][KMAX], E[KMAX],Niv[KMAX],Ap[NMAX],n,m,k=0;
vector <int> A[NMAX];

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

void cit()
{
  fin>>n>>m;
  int i,tata;
  for (i=2;i<=n;++i)
  {
	fin>>tata;
	A[tata].push_back(i);
  }
}

void euler(int x, int niv)
{
	E[++k]=x;
	Niv[k]=niv;
	Ap[x]=k; //prima aparitie
	
	size_t i;
	for (i=0;i<A[x].size();++i)
	{
		euler(A[x][i],niv+1);
		E[++k]=x;
		Niv[k]=niv;
		Ap[x]=k;
	}	
}

void RMQ()
{
	int i,j;	
	for (i=1;i<=k;++i)	
		M[0][i]=i;
		
	
	for (j=1; (1<<j)<=k;++j)
	 for (i=1;i+(1<<j)-1<=k;++i)
	  if (Niv[M[j-1][i]]<Niv[M[j-1][i+(1<<(j-1))]])
			  M[j][i]=M[j-1][i];
		else  M[j][i]=M[j-1][i+(1<<(j-1))];
}

int LCA(int x, int y)
{
	if (Ap[x]>Ap[y]) swap(x,y);
	x=Ap[x]; y=Ap[y];
	int dif=y-x+1, j;
	for (j=0; (1<<j)<=dif; ++j);
	--j;
	if (Niv[M[j][x]]<Niv[M[j][y-(1<<j)+1]]) return E[M[j][x]];	   
	return E[M[j][y-(1<<j)+1]];
}

int main()
{
	cit();
    euler(1,0);
	RMQ();
	
	for (;m;m--)
	{ int x,y;
		fin>>x>>y;
		fout<<LCA(x,y)<<"\n";
	}
	
  return 0;	
}