Cod sursa(job #1468940)

Utilizator al.mocanuAlexandru Mocanu al.mocanu Data 7 august 2015 12:44:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include <stdio.h>
#include <vector>
#define MAX 100005
using namespace std;

int n, m, i, j, x, y, nr;
vector<int> l[MAX];
int rmq[20][2 * MAX], lvl[2 * MAX];
int euler[2 * MAX], log[2 * MAX], indici[MAX];

void constreuler(int x, int nivel);
void constrRMQ();
int LCA();

int main(){
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(i = 2; i <= n; i++){
		scanf("%d", &x);
		l[x].push_back(i);
	}

	constreuler(1, 0);
	constrRMQ();
	LCA();
	return 0;
}

void constreuler(int x, int nivel){
	euler[++nr] = x;
	indici[x] = nr;
	lvl[nr] = nivel;
	int i;
	for(i = 0; i < l[x].size(); i++){
		constreuler(l[x][i], nivel + 1);
		euler[++nr] = x;
		lvl[nr] = nivel;
	 }
}

void constrRMQ(){
	int i, j;
	for(i = 2; i <= nr; i++)
		log[i] = log[i / 2] + 1;
	for(i = 1; i <= nr; i++)
		rmq[0][i] = i;
	for(i = 1; i <= log[nr]; i++)
		for(j = 1; j <= nr - (1<<i) + 1; j++)
			if(lvl[rmq[i - 1][j]] < lvl[rmq[i - 1][j + (1<<(i-1))]])
				rmq[i][j] = rmq[i - 1][j];
			else
				rmq[i][j] = rmq[i - 1][j + (1<<(i-1))];
}

int LCA(){
	int u, v, d;
	for(i = 0; i < m; i++){
		scanf("%d%d", &u, &v);
		u = indici[u];
		v = indici[v];

		if(u > v)
			swap(u, v);

		d = log[v - u + 1];
		if(lvl[rmq[d][u]] < lvl[rmq[d][v - (1<<d) + 1]])
			printf("%d\n", euler[rmq[d][u]]);
		else
			printf("%d\n", euler[rmq[d][v - (1<<d) + 1]]);
	}
}