Cod sursa(job #561556)

Utilizator andra23Laura Draghici andra23 Data 20 martie 2011 19:34:16
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

const int maxn = 100010;
int t[maxn], level[maxn], a[maxn];
int nodes[5*maxn], h[5*maxn], logaritm[5*maxn];
vector <int> sons[maxn];
int c[maxn][25];
ofstream g("lca.out");

void dfs(int nod, int &i) {
	i++;
	nodes[i] = nod;
	h[i] = level[nod];
	a[nod] = i;
	for (int j = 0; j < sons[nod].size(); j++) {
		level[sons[nod][j]] = level[nod] + 1;
		dfs(sons[nod][j], i);	
		i++;
		nodes[i] = nod;
		h[i] = level[nod];
	}	
}

void rmq(int n) {
	
	for (int i = 1; i <= n; i++)
		c[i][0] = i;
	
	for (int j = 1; (1 << j) <= n; j++)
		for (int i = 1; i <= n && i + (1 << j) - 1 <= n; i++) {
			c[i][j] = c[i][j-1];
			if (h[c[i+(1<<(j-1))][j-1]] < h[c[i][j]])
				c[i][j] = c[i+(1<<(j-1))][j-1];		
		}
}

int main() {
	ifstream f("lca.in");
	
	int m, n;
	f >> n >> m;
	
	int x, y;
	for (int i = 2; i <= n; i++) {
		f >> x;
		t[i] = x;
		sons[x].push_back(i);	
	}
	
	level[1] = 1;
	int l = 0;
	dfs(1, l);
	
	rmq(l);
	
	logaritm[1] = 0;
	x = 2;
	for (int i = 2; i <= l; i++) {
		if (i == x) {
			logaritm[i] = logaritm[x/2]+1;
			x = x*2;
		}
		else 
			logaritm[i] = logaritm[i-1]; 
	}
	
	int p, q;
	for (int i = 1; i <= m; i++) {
		f >> p >> q;
		if (a[p] > a[q]) {
			int aux = p;
			p = q;
			q = aux;
		}
		
		x = a[p];
		y = a[q];
		int length = y-x+1;
		int lg = logaritm[length];
		int pos_min_height = c[x][lg];
		if (h[pos_min_height] > h[c[y-(1<<lg)+1][lg]])
			pos_min_height = c[y-(1<<lg)+1][lg];
		
		g << nodes[pos_min_height] << '\n';	
	}
	
	return 0;
}