Cod sursa(job #1397362)

Utilizator LycrsTrifan Tamara Lycrs Data 23 martie 2015 14:21:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include <fstream>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include<string>

using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");

const int MX=200005;
const int MG=25;

typedef struct nod{
	int val;
	nod *next;
}*ls;

int n, i, j, m,  b, euler[MX], lev[MX], f[MX], x, y, k, o, rmq[MX][MG], lg[MX], S=0;
ls lda[MX];

void add(int x, ls &y){
	ls r=new nod;
	r->val=x;
	r->next=y;
	y=r;	
}

void dfs(int nod, int L){
	
	f[nod]=++S;
	euler[S]=nod;
	lev[S]=L;
	for(ls r=lda[nod]; r; r=r->next)
	{
		dfs(r->val, L+1);
		euler[++S]=nod;
		lev[S]=L;
	}
}

void RMQ(){
	
	for(i=1; i<=S; ++i)
		rmq[i][0]=i;
		
	for(j=1; (1<<j) <=S; ++j)
		for(i=1; i+(1<<j)-1 <= S; ++i)
		{
			rmq[i][j]=rmq[i][j-1];
			if (lev[rmq[i+ (1<<(j-1))][j-1]] < lev[rmq[i][j]])
						rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
		}
}

int LCA(int x, int y){
	
	x=f[x];
	y=f[y];
	
	if (x>y) swap(x, y);
	
	
	 
     int   k=log10(y-x+1)/log10(2); 
     int r=rmq[x][k];
     
     if (lev[rmq[y-(1<<k)+1][k]]<lev[r]) r=rmq[y-(1<<k)+1][k];
     return euler[r];
}

int main()
{
	cin>>n>>m;
	
	for(i=2; i<=n; ++i)
	{
		cin>>x;
		add(i, lda[x]);
	}
	
	dfs(1, 0);		
	RMQ();

	while(m--)
	{
		cin>>x>>y;
		cout<<LCA(x, y)<<'\n';
	}

	return 0;
}