Cod sursa(job #514469)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 18 decembrie 2010 19:31:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
#define maxN 100005

FILE*f=fopen("lca.in","r");
FILE*g=fopen("lca.out","w");

int N,Q,i,T,k,EUL[2*maxN],NIV[2*maxN],PA[maxN],M[20][2*maxN],E[2*maxN],j,x,y;
vector<int>W[100005];
int R,e;

int min(int a,int b){
	if ( a < b )
		return a;
	return b;
}

void dfs(int nod,int nivel){
	EUL[++k] = nod;
	NIV[k] = nivel;
	PA[nod] = k;
	//fprintf(g,"%d ",nivel);
	vector<int>::iterator itt;
	
	for ( itt = W[nod].begin(); itt != W[nod].end() ; ++itt ){
		dfs(*itt,nivel+1);
		EUL[++k] = nod;
		NIV[k] = nivel;
		//fprintf(g,"%d ",nivel);
	}
	
	
}

void RMQ (){
	//M[j][i] = nodul cu nivel minim din secventa ce incepe pe pozitia i si are lungimea 2 ^ j
	int i,j;
	for ( i = 2 ; i <= k ; ++i )
		E[i] = E[i/2] + 1;
	for ( i = 1 ; i <= k ; ++i )
		M[0][i] = i;
	for ( j = 1 ; j <= E[k] ; ++j ){
		for ( i = 1 ; i <= k - (1<<(j)) ; ++i ){
			M[j][i] = M[j-1][i];
			if (NIV[M[j][i]] >  NIV[M[j-1][i+ (1<< (j-1))] ] )
				M[j][i] = M[j-1][i+ (1<< (j-1))];
		}
	}
	
}


int main () {
	
	fscanf(f,"%d %d",&N,&Q);
	
	for ( i = 2 ; i <= N ; ++i ){
		fscanf(f,"%d",&T);
		W[T].push_back(i);
	}
	
	dfs(1,0);
	
	RMQ();
	/*for ( i = 1 ; i <= k ; ++i )
		fprintf(g,"%d ",EUL[i]);
	fprintf(g,"\n");
	for ( i = 1 ; i <= k ; ++i )
		fprintf(g,"%d ",NIV[i]);
	fprintf(g,"\n");
	for ( i = 1 ; i <= k ; ++i )
		fprintf(g,"%d ",PA[i]);
	*/
	while ( Q-- ){
		fscanf(f,"%d %d",&x,&y);
		if ( PA[x] > PA[y] )
			swap(x,y);
		e = E[PA[y] - PA[x] +1];
		R = M[e][PA[x]];
		if ( NIV[M[e][PA[x]]] > NIV[M[e][PA[y] - (1 << e) + 1 ]] )
			R = M[e][PA[y] - (1 << e) + 1 ];
		fprintf(g,"%d\n",EUL[R]);
	}
	
	fclose(f);
	fclose(g);
	
	return 0;
}