Cod sursa(job #492930)

Utilizator klamathixMihai Calancea klamathix Data 16 octombrie 2010 13:46:51
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include<cstdio>
#include<fstream>
#include<vector>
#include<algorithm>
const int maxn = 100005;
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

vector <int> G[maxn];
int i , j,  n , m , x , y , A[19][maxn] , lev[maxn];

void DF ( int node , int depth ) {
	lev[node] = depth;
	for(int i = 0 ; i < G[node].size() ; ++i )
		DF ( G[node][i] , depth + 1 );
}

int lca ( int x , int y ) { 
	int i , logx , logy;
	if ( lev[x] < lev[y] ) swap(x,y);
	for( logx = 0 ; ( 1 << logx ) < lev[x] ; ++logx);
	for( logy = 0 ; ( 1 << logy ) < lev[y] ; ++logy);
	
	for(i = logx ; i >= 0 ; --i )
		if ( lev[x] - lev[y] >= ( 1 << i ) )
			x = A[i][x];
	
	if ( x == y ) return x;
		
	for ( ; logy >= 0 ; -- logy ) 
		if ( A[logy][x] && A[logy][x] != A[logy][y] )
			x = A[logy][x],
			y = A[logy][y];
			
	return A[0][x];
}
	

int main()
{
	//freopen("lca.in","r",stdin);
	//freopen("lca.out","w",stdout);
	
	//scanf("%d %d",&n,&m);
	fin >> n >> m;
	
	for( i = 2 ; i <= n ;++i ) {
		//scanf("%d",&A[0][i]);
		fin >> A[0][i];
		G[A[0][i]].push_back(i);
	}
	
	for( j = 1 ; ( 1 << j ) < n ; ++j ) 
		for( i = 2 ; i <= n ; ++i ) 
			A[j][i] = A[j - 1][A[j - 1][i]];
		
	DF(1 , 0);
	
	for( i = 1 ; i <= m ; ++i ) {
		//scanf("%d %d",&x,&y);
		//printf("%d\n",lca(x,y));
		fin >> x >> y;
		fout << lca ( x , y ) << "\n";
	}
	
return 0;
}