Cod sursa(job #902585)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 1 martie 2013 15:16:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <fstream>
#include <vector>
#define lmax 18
#define nmax 100100
#define pb push_back
#define mkp make_pair
#define Level(i) Euler[i].second
using namespace std;

vector < pair<int,int> > Euler;
vector <int> Arb[nmax];
int N,M,First[nmax],Log[2*nmax],Rmq[lmax][2*nmax];

int LCA(int x,int y) {
	
	x=First[x];
	y=First[y];
	
	if(x>y) 
		swap(x,y);
	
	if(Level( Rmq[Log[y-x+1]][x] ) < Level( Rmq[Log[y-x+1]][y-(1<<Log[y-x+1])+1] ))
		return Euler[Rmq[Log[y-x+1]][x]].first;
	else
		return Euler[Rmq[Log[y-x+1]][y-(1<<Log[y-x+1])+1]].first;
	
}
void Dfs(int Nod,int level) {
	
	First[Nod]=Euler.size();
	Euler.pb(mkp(Nod,level));
	
	for(int i=0;i<Arb[Nod].size();i++) {
		Dfs(Arb[Nod][i],level+1);
		Euler.pb(mkp(Nod,level));
		}
	
}
void init() {
	
	int i,j;
	
	Euler.pb(mkp(0,0));
	
	Dfs(1,0);
	
	N<<=1;
	
	for(i=2;i<=N;i++)
		Log[i]=Log[i>>1]+1;
	
	for(i=1;i<=N;i++)
		Rmq[0][i]=i;
	
	for(i=1;(1<<i)<=N;i++)
		for(j=1;j+(1<<i)-1<=N;j++)
			if(Level( Rmq[i-1][j] )<Level( Rmq[i-1][j+(1<<(i-1))] ))
				Rmq[i][j]=Rmq[i-1][j];
			else
				Rmq[i][j]=Rmq[i-1][j+(1<<(i-1))];
	
}
void read(ifstream & in) {

	int i,x;
	
	in>>N>>M;
	
	for(i=2;i<=N;i++) {
		
		in>>x;
		Arb[x].pb(i);
		
		}
	
}
int main() {
	
	int x,y;
	ifstream in("lca.in");
	ofstream out("lca.out");
	
	read(in);
	init();
	
	while(M--) {
		
		in>>x>>y;
		out<<LCA(x,y)<<'\n';
		
		}
	
	in.close();
	out.close();
	
	return 0;
	
}