Cod sursa(job #1550428)

Utilizator al.mocanuAlexandru Mocanu al.mocanu Data 13 decembrie 2015 18:14:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.1 kb
#include <stdio.h>
#include <vector>
#define MAX 100005
#define NIV 18
#define min(a, b) (lvl[a] < lvl[b] ? a : b)
using namespace std;

int n, m, p, euler[2 * MAX], nr = 1, a, b;
int rmq[NIV][2 * MAX], log[2 * MAX], appear[MAX], lvl[MAX];
vector<int> l[MAX];

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

int query(int x, int y){
	if(x > y)
		swap(y, x);
	int d = log[y - x + 1];
	return min(rmq[d][x], rmq[d][y - (1<<d) + 1]);
}

int main(){
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 2; i <= n; i++){
		scanf("%d", &p);
		l[p].push_back(i);
	}
	dfs(1, 0);
	log[1] = 0;
	nr--;
	for(int i = 1; i <= nr; i++){
		rmq[0][i] = euler[i];
		log[i + 1] = log[(i + 1) / 2] + 1;
	}
	
	for(int i = 1; i <= log[nr]; i++)
		for(int j = 1; j <= nr - (1<<i) + 1; j++)
			rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1<<(i-1))]);

	for(int i = 0; i < m; i++){
		scanf("%d%d", &a, &b);
		printf("%d\n", query(appear[a], appear[b]));
	}
	return 0;
}