Cod sursa(job #886979)

Utilizator veleanduAlex Velea veleandu Data 23 februarie 2013 14:22:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

#define max_n 100005
#define fi first
#define se second
#define FORIT( it,v ) for( typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it )

pair<int,int> Parcurgere[ 2*max_n ], Rmk[ 2*max_n ][ 20 ];
bool Viz[ max_n ];
int First[ max_n ], Log[ 2*max_n ];
int a,b,d,n,m,q,f,i;
vector<int> Vertex[ max_n ];

void euler( int nod, int level ){
	Viz[ nod ] = 1;
	Parcurgere[ ++m ] = make_pair( level, nod );
	First[ nod ] = m;
	FORIT( it, Vertex[ nod ] ){
    	if( !Viz[ *it ] ){
			euler( *it, level+1 );
			Parcurgere[ ++m ] = make_pair( level, nod );
		}
	}
}

pair<int,int> min( pair<int,int> a, pair<int,int> b ){
	if ( a.fi < b.fi )
		return a;
	return b;
}
void make_rmk(){
	int i,l;
	Log[ 0 ] = 0;
	Log[ 1 ] = 0;
	for( i=2; i<=m; ++i ){
		Log[ i ] = Log[ i>>1 ] + 1;
	}
	for( i=1; i<=m; ++i ){
		Rmk[ i ][ 0 ] = Parcurgere[ i ];
	}
	for( l=1; (1<<l) <=m; ++l ){
		for( i=1; i+(1<<l)-1 <=m; ++i ){
			Rmk[ i ][ l ] = min( Rmk[ i ][ l-1 ], Rmk[ i+(1<<(l-1)) ][ l-1 ] );
		}
	}
	return ;
}

int main(){
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d %d", &n, &q );
	for ( i=2; i<=n; ++i ){
		scanf("%d", &a );
		Vertex[ a ].push_back( i );
	}
	euler( 1, 1 );
 	make_rmk();
    for( ; q; --q ){
		scanf("%d %d", &a, &b );
		a = First[ a ];
		b = First[ b ];
		if ( a > b )
			swap( a,b );
		d = b-a+1;
		i = Log[ d ];
		printf("%d\n", min( Rmk[ a ][ i ], Rmk[ b-(1<<i)+1 ][ i ] ).se );
	}
	return 0;
}