Cod sursa(job #982788)

Utilizator superman_01Avramescu Cristian superman_01 Data 10 august 2013 00:01:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include<fstream>
#include<algorithm>
#include<utility>
#include<queue>
#include<cmath>
#include<stack>
#include<vector>
#include<cstdio>

#define min( a , b ) ((a)<(b)?(a):(b))
#define NMAX 100005
#define LMAX 20

using namespace std;

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

vector < int > G[NMAX];
int N , M , K ;
int first[NMAX] , l[NMAX<<1],lg[NMAX<<1];
int euler[NMAX<<1],rmq[LMAX][NMAX<<1];

void DFS ( int node , int level )
{
	euler[++K] = node ; 
	l[K] = level ;
	first[node] = K ; 
	for( vector < int > :: iterator it = G[node].begin() ; it!= G[node].end() ; ++it )
	{
		DFS( *it , level + 1 );
		euler[++K] = node ;
		l[K] = level;
	}
}

void BuildRMQ ( void )
{
	int i , ii;
	lg[1] = 0 ;
	for( i = 2 ; i <= K ; ++i )
		lg[i] = lg[i/2] + 1 ;
	for( i = 1 ; i <= K ; ++i )
		rmq[0][i] = i ;
	 for(i = 1 ; (1<<i) <=  K ; ++i )
        for(ii = 1 ; ii <= K - (1<<i) +1 ; ++ii )
    {
        int len=1<<(i-1);
 
        rmq[i][ii]=rmq[i-1][ii];
        if(l[rmq[i-1][ii+len]] < l [rmq[i-1][ii]])
            rmq[i][ii]=rmq[i-1][ii+len];
    }
	
}

int main ( void )
{
	int i , j , x, left , right ;
	in >> N >> M ;
	for( i = 2 ; i <= N ; ++i )
	{
		in >> x;
		G[x].push_back(i);
	}
	DFS( 1 , 0 );
	BuildRMQ();
	for( ; M > 0 ; -- M )
	{
		in >> left >> right ;
		left = first [ left ] ; right = first[ right ];
		if( left > right )
			swap( left , right ) ;
		int diff , sx , x;
		diff = right - left + 1 ;
		int la = lg[diff] ;
		( l[rmq[la][left]] > l[rmq[la][left + diff - (1 << la)]] ? out << euler[rmq[la][left + diff - (1 << la)]] : out << euler[rmq[la][left]]);
		out << "\n";
	}
	in.close();
	out.close();
	return 0 ;
		
}