Cod sursa(job #1133414)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 4 martie 2014 20:55:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

#define NMAX 100001
#define EMAX 300001

struct nod {
	int U;
	nod *next;
};
nod *v[NMAX];

void add(int A, int B) {
	nod *P = new nod;
	P->U = B;
	P->next = v[A];
	v[A] = P;
}

int i, j, T, N, M, K;
int p, x, y;

int Log[EMAX];
bool used[NMAX];
int Euler[EMAX];
int First[NMAX];
int level[NMAX];

struct rmq {
	int v;
	int node;
};
rmq dp[20][EMAX];

void DFS(int node) {
	used[node] = true;
	Euler[++K] = node;
	First[node] = K;
	for (nod *it = v[node]; it; it = it->next) {
		if (!used[it->U]) {
			level[it->U] = level[node] + 1;
			DFS(it->U);
			Euler[++K] = node;
		}
	}
}

int main() {
	fin >> N >> M;
	for (i = 2; i <= N; ++i) {
		fin >> T;
		add(i, T);
		add(T, i);
	}
	DFS(1);
	memset(dp, 0x3f3f3f3f, sizeof(dp));
	for (i = 1; i <= K; ++i) {
		dp[0][i].v = level[Euler[i]];
		dp[0][i].node = Euler[i];
	}
	for (i = 2; i <= K; ++i) Log[i] = Log[(i >> 1)] + 1;
	for (i = 1; (1 << i) <= K; ++i) {
		for (j = 1; j + (1 << i) - 1 <= K; ++j) {
			if (dp[i - 1][j].v < dp[i - 1][j + (1 << (i - 1))].v) {
				dp[i][j].v = dp[i - 1][j].v;
				dp[i][j].node = dp[i - 1][j].node;
			}
			else {
				dp[i][j].v = dp[i - 1][j + (1 << (i - 1))].v;
				dp[i][j].node = dp[i - 1][j + (1 << (i - 1))].node;
			}
		}
	}
	for (i = 1; i <= M; ++i) {
		fin >> x >> y;
		if (First[y] < First[x]) swap(x, y);
		p = Log[First[y] - First[x] + 1];
		if (dp[p][First[x]].v < dp[p][First[y] - (1 << p) + 1].v) 
			fout << dp[p][First[x]].node << '\n';
		else
			fout << dp[p][First[y] - (1 << p) + 1].node << '\n';
	}
	return 0;
}