Cod sursa(job #509308)

Utilizator cosmyoPaunel Cosmin cosmyo Data 10 decembrie 2010 20:40:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <fstream>
#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)], l[2*N], p, poz[N], pz[20][N * 2], P[20] ;
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)
		 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) {
				pz[i][j] = pz[i - 1][j];
					if( h[pz[i][j]] >h[pz[i - 1][j + p]] )
						 pz[i][j] = pz[i - 1][j + p]; 
			}

}


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

int main() {
	ifstream fin("lca.in");
	ofstream fout("lca.out");
	
	int j,i, x, y;
	fin>>n>>m;
		
		for( i = 2; i <= n; ++i)
			fin>>y, a[i].push_back(y), a[y].push_back(i);
	v[1] = 1;
	dfs(1);
	precalc();

	
		for( i = 1; i <=m ;++i) {
			fin>>x>>y;
			if(poz[x]>poz[y]) {
				j = x;
				x = y;
				y = j;
			}
		
			fout<<eul[RMQ(poz[x],poz[y])]<<'\n';
		}
	fin.close();
	fout.close();
	return 0;
}