Cod sursa(job #1166137)

Utilizator roots4Irimia Alexandru Gabriel roots4 Data 3 aprilie 2014 11:46:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include<fstream>
#include<vector>


using namespace std;

#define max_n 100010

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

int n , m , T , k , x , y;
vector<int>L[max_n];
int Nivel[max_n] , First[max_n];
int Rmq[20][3*max_n] , P[3*max_n];

void read(){

	f>>n>>m;

	for( int i = 2 ; i <= n ; i++ ){
		f>>T;
		L[T].push_back(i);
	}

}

void dfs( int nod,  int niv ){

	Rmq[0][++k] = nod;
	Nivel[nod] = niv;
	First[nod] = k;

	for( int i = 0 ; i < L[nod].size() ; i++ ){
		dfs( L[nod][i] , niv + 1 );
		Rmq[0][++k] = nod;
	}

}

void rmq(){

	for( int i = 1 ; (1<<i) <= k ; i++ ){
		for( int j = 1 ; j <= ( k - (1<<i) + 1 ) ; j++ ){
			Rmq[i][j] = Rmq[i-1][j + (1<<(i-1))];
			if( Nivel[ Rmq[i][j] ] > Nivel[Rmq[i-1][j]] )
				Rmq[i][j] = Rmq[i-1][j];
		}
	}

	for( int i = 2 ; i <= k ; i++ )
		P[i] = P[i/2] + 1;

}

void swap( int &x , int &y ){
	int aux = x;
	x = y;
	y = aux;
}

int lca( int x, int y ){

	int p1 = First[x] , p2 = First[y];

	if( p1 > p2 )
		swap(p1 , p2);

	int p = P[p2 - p1 + 1];

	int sol = Rmq[p][p2 - (1<<p) + 1];

	if( Nivel[ sol ] > Nivel[Rmq[p][p1]] )
		sol = Rmq[p][p1];
	return sol;
}

void solve(){

	for( int i = 1 ; i <= m ; i++ ){
		f>>x>>y;
		g<<lca(x , y)<<"\n";
	}

}

int main(){

	read();

	dfs( 1 , 1 );

	rmq();

	solve();

	return 0;
}