Cod sursa(job #1453674)

Utilizator theprdvtheprdv theprdv Data 24 iunie 2015 07:56:10
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define MAXN 100001
#define left (n << 1)
#define right (left + 1)
#define mid ((l + r) >> 1)
#define foreach(V) for(vector <int>::iterator it = (V).begin(); it != (V).end(); ++it)

using namespace std;

int N, M, no, a, b, sol;
int T[4 * MAXN], Lev[2 * MAXN], H[2 * MAXN], Fs[2 * MAXN];
vector <int> G[MAXN];

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

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

void query(int n = 1, int l = 1, int r = no){
	if (a <= l && r <= b){
		if (Lev[T[n]] < Lev[sol] || !sol) sol = T[n];
		return;
	}
	if (a <= mid) query(left, l, mid);
	if (b > mid) query(right, mid + 1, r);
}

void build(int n = 1, int l = 1, int r = no){
	if (l == r){
		T[n] = H[l];
		return;
	}
	build(left, l, mid), build(right, mid + 1, r);

	if (Lev[T[left]] < Lev[T[right]]) T[n] = T[left];
	else T[n] = T[right];
}

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();
	build();

	for (int x, y; M; --M, sol = 0){
		scanf("%d %d", &x, &y);
		a = Fs[x], b = Fs[y];
		if (a > b) a ^= b ^= a ^= b;
		query();
		printf("%d\n", sol);
	}
	return 0;
}