Cod sursa(job #1537877)

Utilizator MesesanPaulMesesanPaul MesesanPaul Data 28 noiembrie 2015 11:30:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 100005;

vector <int> v[NMAX];
int logg[2*NMAX];
int rmq[18][2*NMAX];
int nod[18][2*NMAX];
int euler[2*NMAX];
int first[NMAX];
int lev[NMAX];
int n, m;
int cnt;

void dfs(int node){
	euler[++cnt]=node;
	first[node]=cnt;
    for(int it=0; it<v[node].size();++it){
		lev[v[node][it]]=lev[node]+1;
		dfs(v[node][it]);
		euler[++cnt]=node;
	}
}

void logg_init(){
	for(int i=2;i<=cnt;++i){
		logg[i]=logg[i/2]+1;
	}
}

void rmq_init(){
	for(int i=1;i<=cnt;++i){
		rmq[0][i]=lev[euler[i]];
		nod[0][i]=euler[i];
	}
	for(int i=1;(1<<i)<=cnt;++i){
		for(int j=1;j+(1<<(i-1))-1<=cnt;++j){
			if(rmq[i-1][j]<rmq[i-1][j+(1<<(i-1))]){
				rmq[i][j] = rmq[i-1][j];
				nod[i][j] = nod[i-1][j];
			}
			else{
				rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
				nod[i][j] = nod[i-1][j+(1<<(i-1))];
			}
		}
	}
}

int query(int x, int y){
	x = first[x];
	y = first[y];
	if(x>y){
		swap(x, y);
	}
	int i = logg[y-x+1];
	if(rmq[i][x]<rmq[i][y-(1<<i)+1]){
		return nod[i][x];
	}
	else{
		return nod[i][y-(1<<i)+1];
	}
}

int main(){
	int x, y;
	file_read >>n>>m;
	for(int i=1;i<n;++i){
		file_read >>x;
		v[x].push_back(i+1);
	}

	dfs(1);
    
	logg_init();
	rmq_init();
	
	for(int i=1;i<=m;++i){
		file_read >>x>>y;
		file_write <<query(x, y)<<"\n";
	}
	return 0;
}