Cod sursa(job #408254)

Utilizator dexter_dexMutascu Adrian - Dragos dexter_dex Data 2 martie 2010 22:15:38
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <stdio.h>
#include <vector>

#define Nmax 100005

using namespace std;

vector <int> A[Nmax];
int e[Nmax], N[2 * Nmax], log[2 * Nmax], EULER[2*Nmax], RMQ[20][2*Nmax];
int i, n, m, x, k = 1, y, q, aux;



FILE * f = fopen ("lca.in", "r");
FILE * g = fopen ("lca.out", "w");
	
int minim(int a, int b){
	if (N[a]<N[b]) 
		return a;
	return b;
}

void citire(){
	fscanf(f, "%d %d", &n, &m);
	for (i = 1 ; i < n ; i++){
		fscanf(f, "%d", &x);
		A[x].push_back(i+1);
	}
}

void dfs(int nod, int niv){
	
	int i, l;
	l = A[nod].size();
	
	for (i = 0 ; i < l ; i++){
		x = A[nod][i];
		
		N[++k] = niv;
		EULER[k] = x;
		if ( !e[x] )
			e[x] = k;
		
		dfs(x, niv+1);
		
		N[++k] = niv - 1;
		EULER[k] = nod;
	}
}


void logaritm(){
	n = k;
	
	RMQ[0][1] = 1;
	
	for (i = 2 ; i <= n ; i++){
		log[i] = log[i>>1] + 1;	
		RMQ[0][i] = i;
	}
}

void preprocesare(){
	for (k = 1 ; i <= log[n] ; k++){
		aux = (1<<k) - 1
		for (i = 1 ; i + aux <= n ; i++)
			RMQ[k][i] = minim( RMQ[k-1][i], RMQ[k-1][i + (1<<k-1)] );
	}	
}

void rezolvare(){
	for (i = 1 ; i <=  m ; i++){
		fscanf (f, "%d %d", &x, &y);
		x = e[x];
		y = e[y];
		if (y < x){
			aux = x;
			x = y; 
			y = aux;
		}			
		q = log [y-x+1];
		
		fprintf (g, "%d\n", EULER[minim(RMQ[q][x], RMQ[q][y - (1<<(q)) + 1])]);
	}
}

int main(){
	citire();

	N[1] = 0;
	e[1] = 1;
	EULER[1] = 1;
	
	dfs(1,1);
	
	logaritm();
	preprocesare();
	rezolvare();
	
	fclose(f);
	fclose(g);
	return 0;
}