Cod sursa(job #762248)

Utilizator theodora_maneaManea Theodora Maria theodora_manea Data 29 iunie 2012 15:27:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define max_n 100005
#define INF 0x3f3f3f3f

int n,m,k,x,y,st,dr,sol,Esol;
int niv[max_n << 1];
int E[max_n << 1];
int ap[max_n];
int a[max_n << 4];

vector <int> g[max_n];
vector <int>::iterator it;

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

void DFS(int nod,int nivel) {
	E[++k]=nod;
	niv[k]=nivel;
	ap[nod]=k;
	vector <int>::iterator it;
	for (it=g[nod].begin(); it!=g[nod].end(); it++) {
		DFS(*it, nivel+1);
		
		E[++k]=nod;
		niv[k]=nivel;
	}
}


void build_arb(int nod,int st,int dr)
{ 
	int nod1,nod2;
	int mij;
	if(st==dr)
	{
		a[nod]=st;
		return;
	}
	mij=(st+dr)/2;
	nod1=nod<<1;
	nod2=nod1 | 1;
    build_arb(nod1,st,mij);
	build_arb(nod2, mij+1,dr);

	if(niv[a[nod1]]<=niv[a[nod2]])
		a[nod]=a[nod1];
	else
		a[nod]=a[nod2];
}


void interogare(int nod,int li,int lf)
{
	int mij,nod1,nod2;
	if(st<=li && lf<=dr)
	{
		if(niv[a[nod]] < Esol)
			sol=E[a[nod]],
			Esol=niv[a[nod]];
		return;
	}
    mij=(li+lf)/2;
	nod1=nod << 1;
	nod2=nod1 | 1;
	if(st<=mij) interogare(nod1, li, mij);
	if(mij<dr) interogare(nod2, mij+1, lf);
}


int LCA(int x, int y)
{
	st=ap[x], dr=ap[y];
	if(st>dr) swap(st, dr);
	sol=Esol= INF;
	interogare(1,1,k);
    return sol;
}

int main () {
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d",&n,&m);
	citire();
	k=0;
	DFS(1,0);
	build_arb(1,1,k);
	for (int i=1; i<=m; i++) {
		scanf("%d%d",&x,&y);
		printf("%d\n",LCA(x,y));
	}
	return 0;
}