Cod sursa(job #1454048)

Utilizator theprdvtheprdv theprdv Data 25 iunie 2015 12:58:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.18 kb
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define MAXN 100001
#define foreach(V) for(vector <int>::iterator it = (V).begin(); it != (V).end(); ++it)

using namespace std;

int N, M, no, Fs[MAXN], Lev[MAXN], Log[2 * MAXN], RMQ[18][2 * MAXN];
vector <int> G[MAXN];

inline int min(int a, int b) { return Lev[a] < Lev[b] ? a : b; }

void DFS(int n = 1, int lv = 1){
	RMQ[0][++no] = n;
	Fs[n] = no;
	Lev[n] = lv;

	foreach(G[n])
		DFS(*it, lv + 1),
		RMQ[0][++no] = n;
}

int main(){
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);

	scanf("%d %d", &N, &M);
	for (int i = 2, x; i <= N; ++i)
		scanf("%d", &x),
		G[x].push_back(i);
	DFS();
	for (int i = 2; i <= N << 1; ++i) Log[i] = Log[i >> 1] + 1;

	for (int i = 1; (1 << i) <= no; ++i)
		for (int j = 1; j <= no - (1 << i) + 1; ++j)
			RMQ[i][j] = min(RMQ[i - 1][j], RMQ[i - 1][j + (1 << (i - 1))]);

	for (int x, y, diff, row; M; --M){
		scanf("%d %d", &x, &y);
		x = Fs[x], y = Fs[y];
		if (y < x) x ^= y ^= x ^= y;
		diff = y - x + 1;
		row = Log[diff];
		printf("%d\n", min(RMQ[row][x], RMQ[row][x + diff - (1 << row)]));
	}

	return 0;
}