Cod sursa(job #1009105)

Utilizator teoionescuIonescu Teodor teoionescu Data 12 octombrie 2013 15:07:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.13 kb
#include<fstream>
#include<vector>
#define Emin(x,y) ( E[x] < E[y] ? x : y)
#define min(x,y) ( x < y ? x : y)
#define doila(x) (1<<x)
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int Nmax = 100005;
vector<int> G[Nmax];
int E[2*Nmax],K;
int first[Nmax];
int N,M;
void Dfs(int i){
	E[++K]=i;
	if(!first[i]) first[i]=K;
	for(vector<int>::iterator it=G[i].begin();it!=G[i].end();++it){
		Dfs(*it);
		E[++K]=i;
	}
}
int rmq[18][2*Nmax];
int lg[2*Nmax];
void procRMQ(){
	int i,j;
	for(i=2;i<=K;i++) lg[i]=lg[i/2]+1;
	for(j=1;j<=K;j++) rmq[0][j]=j;
	for(i=1;i<=lg[K];i++){
		for(j=1;j<=K-doila(i)+1;j++){
			rmq[i][j]=Emin(rmq[i-1][j],rmq[i-1][j+doila(i-1)]);
		}
	}
}
int RMQ(int x,int y){
	int dist=y-x+1;
	int block=lg[dist];
	int shift=dist-doila(block);
	return Emin(rmq[block][x],rmq[block][x+shift]);
}
int main(){
	in>>N>>M;
	for(int i=2;i<=N;i++){
		int t;
		in>>t;
		G[t].push_back(i);
	}
	Dfs(1);
	procRMQ();
	for(;M;--M){
		int x,y;
		in>>x>>y;
		x=first[x];
		y=first[y];
		if(y<x){
			int aux=x;
			x=y;
			y=aux;
		}
		out<<E[RMQ(x,y)]<<'\n';
	}
	return 0;
}