Cod sursa(job #561529)

Utilizator andra23Laura Draghici andra23 Data 20 martie 2011 17:53:27
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

const int maxn = 100010;
int t[maxn], level[maxn];
vector <int> sons[maxn];
int c[maxn][25];
ofstream g("lca.out");
	
void findLevel(int nod) {
	for (int i = 0; i < sons[nod].size(); i++) {
		level[sons[nod][i]] = level[nod] + 1;
		findLevel(sons[nod][i]);	
	}	
}

int findAncestor(int a, int b) {
	if (level[a] < level[b]) {
		int aux = a;
		a = b;
		b = aux;	
	}
	
	int log = 0;
	for (log = 0; (1 << log) <= level[a]; log++);
	log--;
	
	for (int i = log; i >= 0; i--)
		if (c[a][i] != -1 && level[c[a][i]] >= level[b])
			a = c[a][i];
	
	if (a == b)
		return a;
	
	for (int i = log; i >= 0; i--) 
		if (c[a][i] != -1 && c[a][i] != c[b][i]) {
			a = c[a][i];
			b = c[b][i];	
		}
		
	return t[a];
}

int main() {
	ifstream f("lca.in");
	
	int m, n;
	f >> n >> m;
	
	int x;
	for (int i = 2; i <= n; i++) {
		f >> x;
		t[i] = x;
		sons[x].push_back(i);	
	}
	
	level[1] = 1;
	findLevel(1);
	
	for (int i = 1; i <= n; i++)
		for (int j = 1; (1 << j) <= n; j++)
			c[i][j] = -1;
			
	for (int i = 1; i <= n; i++)
		c[i][0] = t[i];
	c[1][0] = -1;
	
	for (int j = 1; (1 << j) <= n; j++)
		for (int i = 1; i <= n; i++)
			if (c[i][j-1] != -1)
				c[i][j] = c[c[i][j-1]][j-1];
	
	/*
	for (int i = 1; i <= n; i++) {
		for (int j = 0; (1 << j) <= n; j++)
			g << c[i][j] << " ";
		g << endl;
	}
	*/
	
	int a, b;
	for (int li = 1; li <= m; li++) {
		f >> a >> b;
		x = findAncestor(a, b);
		g << x << '\n';
	}
		
	return 0;
}