Cod sursa(job #638941)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 21 noiembrie 2011 23:13:54
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.16 kb
#include<fstream>
#include<vector>
using namespace std;
vector <int> v[100100];
int n,nr,rmq[200100][20];
int euler[200100],first[200100],lvl[200100],log_2[200100];
int lca(int a,int b) {
	int termeni,lp,k,sol;
	a=first[a];
	b=first[b];
	if(a>b) swap(a,b);
	termeni=b-a+1;
	lp=log_2[termeni];
	k=b-(1<<lp)+1;
	sol=rmq[a][lp];
	if(lvl[sol]>lvl[rmq[k][lp]])
		sol=rmq[k][lp];
	return euler[sol];
}
void rmq_() {
	int i,j,lp;
	for(i=1;i<=nr;i++)
		rmq[i][0]=i;
	for(i=2;i<nr;i++)
		log_2[i]=log_2[i/2]+1;
	for(j=1;(1<<j)<=nr;j++)
		for(i=1;i+(1<<j)-1<=nr;i++) {
			lp=1<<(j-1);
			rmq[i][j]=rmq[i][j-1];
			if(lvl[rmq[i+lp][j-1]]<lvl[rmq[i][j]])
				rmq[i][j]=rmq[i+lp][j-1];
			}
}
void dfs(int nod,int level) {
	euler[nr]=nod;
	first[nod]=nr;
	lvl[nr++]=level;
	for(int i=0;i<v[nod].size();i++) {
		dfs(v[nod][i],level+1);
		euler[nr]=nod;
		lvl[nr++]=level;
		}
}
int main() {
	int i,x,y,m;
	ifstream in("lca.in");
	ofstream out("lca.out");
	in>>n>>m;
	for(i=2;i<=n;i++) {
		in>>x;
		v[x].push_back(i);
		}
	dfs(1,0);
	rmq_();
	for(i=0;i<m;i++) {
		in>>x>>y;
		out<<lca(x,y)<<'\n';
		}
	in.close();
	out.close();
	return 0;
}