Cod sursa(job #591975)

Utilizator vladtarniceruVlad Tarniceru vladtarniceru Data 26 mai 2011 09:40:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
# include <fstream>
# include <vector>
using namespace std;

ifstream f ("lca.in");
ofstream g ("lca.out");

vector <int> a[100010];
int n, m, i, j, v[200010], cit, l[200010], x, y;
int poz[200010], rmq[19][200010], vlg[200010];

void dfs (int nod, int niv){
	v[++v[0]] = nod;
	l[++l[0]] = niv;
	int siz = a[nod].size ();
	for (int k = 0; k < siz; ++k){
		int val = a[nod][k];
		dfs (val, niv + 1);
		v[++v[0]] = nod;
		l[++l[0]] = niv;
	}
}

inline int minim (int a, int b){
	if (a < b) return a;
	return b;
}

int query (int x, int y){
	int dif = y - x + 1;
	int lin = vlg[dif];
	if (l[rmq[lin][x]] < l[rmq[lin][y + 1 - (1 << (lin))]])
		return v[rmq[lin][x]];
	else
		return v[rmq[lin][y + 1 - (1 << (lin))]];
}

int main (){
	f >> n >> m;
	
	for (i = 2; i <= 200000; ++i)
		vlg[i] = vlg[i >> 1] + 1;
	
	for (i = 2; i <= n; ++i){
		f >> cit;
		a[cit].push_back (i);
	}
	
	dfs (1, 0);
	
	for (i = 1; i <= l[0]; ++i)
		rmq[0][i] = i;
	
	for (i = 1; (1 << i) <= l[0]; ++i){
		int val = l[0] - (1 << i) + 1;
		for (j = 1; j <= val; ++j){
			if (l[rmq[i - 1][j]] < l[rmq[i - 1][j + (1 << (i - 1))]])
				rmq[i][j] = rmq[i - 1][j];
			else
				rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
		}
	}
	
	for (i = 1; i <= v[0]; ++i)
		if (!poz[v[i]]) poz[v[i]] = i;
	
	for (; m > 0; --m){
		f >> x >> y;
		
		x = poz[x]; y = poz[y];
		if (x > y) x ^= y ^= x ^= y;
		
		g << query (x, y) << '\n';
	}
	g.close ();
	return 0;
}