Cod sursa(job #509298)

Utilizator cosmyoPaunel Cosmin cosmyo Data 10 decembrie 2010 20:21:46
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <cstdio>
#include <vector>
using namespace std;
inline int min( int a, int b ) {
	return a<b?(a):(b);
}
const int N = 100005;

int nr,v[N], n, m, h[2* ( N +1 )], eul[2 * (N + 1)], rmq[20][N * 2], l[2*N], p, poz[N], pz[20][N * 2] ;
vector<int> a[N];

int dfs( int k ) {
	int i;
	eul[ ++nr ] = k;
	poz[k] = nr;
		for( i = 0; i < a[k].size(); ++i)
			if( !v[a[k][i]] ) 
		     v[a[k][i]] = v[k] + 1,dfs(a[k][i]),
		eul[ ++nr] = k, poz[k] = nr;
}

inline void precalc() {
	int i, j;
	
	for(i = 1; i <= nr; ++i)
		h[i] = v[eul[i]];
	
	p = 1;
	j = -1;

		for(i = 1; i <= nr; ++i) {
			if ( i == p )
				++j,p*=2;
			if( i <= p )
				l[i] = j;
			
		}

	p = 1;
	
	for( i = 1; i <= nr; ++i)
		rmq[0][i] = h[i], pz[0][i]= i;
		for(i = 1; i <= l[nr]; ++i, p*=2)
			for(j = 1; j<= nr; ++j) 
			if(j + p*2 <= nr +1) {
				rmq[i][j] = rmq[i - 1][j];
				pz[i][j] = pz[i - 1][j];
					if( rmq[i][j] > rmq[i - 1][j + p] )
						rmq[i][j] = rmq[i - 1][j + p], pz[i][j] = pz[i - 1][j + p]; 
			}

}


inline int RMQ(int i, int j) {
	if( rmq[l[j - i  + 1]][i]< rmq[l[j - i + 1]][j - (1<<l[j - i + 1]) + 1] )
		return pz[l[j - i + 1]][i];
	else
		return pz[l[j - i + 1]][j - (1<<l[j - i + 1]) + 1 ];
}

int main() {
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	
	int j,i, x, y;
	scanf("%d %d", &n, &m);
		
		for( i = 2; i <= n; ++i)
			scanf("%d ", &y), a[i].push_back(y), a[y].push_back(i);
	v[1] = 1;
	dfs(1);
	precalc();

	
		for( i = 1; i <=m ;++i) {
			scanf("%d %d", &x, &y);
			if(poz[x]>poz[y]) {
				j = x;
				x = y;
				y = j;
			}
		
			printf("%d \n",eul[RMQ(poz[x],poz[y])]);
		}
	return 0;
}