Cod sursa(job #974572)

Utilizator tudorv96Tudor Varan tudorv96 Data 17 iulie 2013 16:23:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <fstream>
#include <vector>
#include <list>
using namespace std;

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

#define last (int)(E.size()-1)
#define N 2*n+1
#define min(a,b) ((a < b) ? a : b)

vector <list <int> > g;
vector <vector <int> > rmq;
vector <int> E, f, L, bp;
int n, m;

void swap (int &a, int &b) {
	int aux = a;
	a = b;
	b = aux;
}

void dfs(int x, int val) {
	E.push_back(x);
	L.push_back(val);
	f[x] = last;
	for (list <int> :: iterator it = g[x].begin(); it != g[x].end(); ++it) {
		dfs(*it, val + 1);
		E.push_back(x);
		L.push_back(val);
	}
}

void RMQ() {
	rmq.resize(bp[last]+1);
	for (vector <vector <int> > :: iterator it = rmq.begin(); it != rmq.end(); ++it)
		(*it).resize(last+1);
	for (int i = 1; i <= last; ++i)
		rmq[0][i] = i;
	for (int i = 1; i <= bp[last]; ++i)
		for (int j = 1; j <= last - (1 << i) + 1; ++j) {
			rmq[i][j] = rmq[i-1][j];
			if (L[rmq[i][j]] > L[rmq[i-1][j + (1 << (i - 1))]])
				rmq[i][j] = rmq[i-1][j + (1 << (i - 1))];
		}			
}

int LCA(int x, int y) {
	int a = f[x], b = f[y];
	if (a > b)
		swap (a, b);
	int pow = bp[b - a + 1];
	int res = rmq[pow][a];
	if (L[res] > L[rmq[pow][b + 1 - (1 << pow)]])
		res = rmq[pow][b + 1 - (1 << pow)];
	return E[res];
}

int main() {
	fin >> n >> m;
	E.reserve(N+1);
	L.reserve(N+1);
	bp.resize(N+1);
	f.resize(n+1);
	E.push_back(0);
	L.push_back(0);
	g.resize(n+1);
	for (int i = 2; i <= n; ++i) {
		int x;
		fin >> x;
		g[x].push_back(i);
	}
	dfs(1, 0);
	for (int i = 2; i <= last; ++i)
		bp[i] = bp[i >> 1] + 1;
	RMQ();
	while (m--) {
		int x, y;
		fin >> x >> y;
		fout << LCA(x, y) << "\n";
	}
}