Cod sursa(job #1221063)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 19 august 2014 12:46:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 100010

vector<int> Gr[MAX];
int N, M;
struct Node{
	int X, H;
	Node(){
		X = 0, H = 0;
	}
	Node(int X, int H){
		this->X = X, this->H = H;
	}
};
vector<Node> Euler(1);
int First[MAX], LCA[3 * MAX][19];

void DFS(int X, int H) {
	Euler.push_back(Node(X, H));
	for (int i = 0; i < Gr[X].size(); i++) {
		DFS(Gr[X][i], H + 1);
		Euler.push_back(Node(X, H));
	}
}

int main() {
	int X, Y, K, L, R;
	
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	
	scanf("%d %d", &N, &M);
	for (int i = 2; i <= N; i++) {
		scanf("%d", &X);
		Gr[X].push_back(i);
	}
	
	DFS(1, 0);
	
	for (int i = 1; i < Euler.size(); i++) {
		if (!First[Euler[i].X]) {
			First[Euler[i].X] = i;
		}
	}
	
	for (int i = 1; i < Euler.size(); i++) {
		LCA[i][0] = i;
	}
	
	for (int j = 1; (1 << j) < Euler.size(); j++) {
		for (int i = 1; i + (1 << j) - 1 < Euler.size(); i++) {
			X = LCA[i][j-1];
			Y = LCA[i + (1 << (j-1))][j-1];
			if (Euler[X].H < Euler[Y].H) {
				LCA[i][j] = X;
			} else {
				LCA[i][j] = Y;
			}
		}
	} 
	
	for (int i = 1; i <= M; i++) {
		scanf("%d %d", &X, &Y);
		X = First[X];
		Y = First[Y];
		if (X > Y) swap(X, Y);
		K = (int)(log(Y - X + 1) / log(2));
		L = LCA[X][K];
		R = LCA[Y - (1 << K) + 1][K];
		if (Euler[L].H < Euler[R].H) {
			printf("%d\n", Euler[L].X);
		} else {
			printf("%d\n", Euler[R].X);
		}
	}
	
	return 0;
}