Cod sursa(job #708338)

Utilizator valentin.harsanValentin Harsan valentin.harsan Data 6 martie 2012 18:53:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

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

int n,m,e[200020],lv[200020],pap[200020],nr,rmq[200020][25],mpoz[200020][25],lg[200020];
vector<int> v[100010];

void pEuler(int nod, int niv) {
	int i;
	
	if(pap[nod]==0)
		pap[nod]=nr;
	
	for(i=0;i!=v[nod].size();++i) {
		
		e[++nr]=nod; lv[nr]=niv;
		
		pEuler(v[nod][i],niv+1);
	}
	
	e[++nr]=nod; lv[nr]=niv;
}

void initRMQ() {
	int i,j,l;
	
	for(i=1;i<=nr;++i) {
		rmq[i][0]=lv[i];
		mpoz[i][0]=i;
	}
	
	for(i=1;(1<<i)<=nr;++i)
		for(j=1;j <= nr - (1<<i) + 1;++j) {
			l=(1<<(i-1));
			
			if(rmq[j][i-1] < rmq[j+l][i-1])
				mpoz[j][i] = mpoz[j][i-1];
			else
				mpoz[j][i] = mpoz[j+l][i-1];
			
			rmq[j][i] = min(rmq[j][i-1], rmq[j+l][i-1]);
		}
}

inline int query(int el1, int el2) {
	if(el1>el2) {
		el1^=el2;
		el2^=el1;
		el1^=el2;
	}
	int minpoz,dist = lg[el2 - el1];
	
	if(rmq[el1][dist] > rmq[el2-dist][dist])
		minpoz = mpoz[el1][dist];
	else
		minpoz = mpoz[el2 - dist][dist];
	
	return e[minpoz];
}

int main() {
	int i,p,n1,n2;
	
	in >> n >> m;
	
	for(i=2;i<=n;++i) {
		in >> p;
		v[p].push_back(i);
	}
	
	for(i=2;i<=2*n;++i)
		lg[i] = lg[i>>1] + 1;
	
	pEuler(1,1);
	
	initRMQ();
	
	for(i=1;i<=m;++i) {
		in >> n1 >> n2;
		
		out << query(pap[n1],pap[n2]) << "\n";
	}
	
	return 0;
}