Cod sursa(job #574770)

Utilizator mathboyDragos-Alin Rotaru mathboy Data 7 aprilie 2011 15:23:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <cstdio>
#include <bitset>
#include <vector>
#include <cstring>
#include <string>
#define maxn 100010
using namespace std;

bitset <maxn> viz;
int E[maxn << 1], L[maxn << 1], app[maxn];
int rmq[20][maxn << 1], lg[maxn << 1];
vector <int> G[maxn];
int N, Q, p;
void DFS (int node, int lev)
{	
	viz[node] = 1;

	E[++p] = node;
	L[p] = lev;
	app[node] = p;

	for (vector <int> :: iterator it = G[node].begin (); it != G[node].end (); it++) 
		if (viz[*it] == 0) {
			DFS (*it, lev + 1);
			E[++p] = node;
			L[p] = lev;
		}
}
const int dim = 8192;
char vec[dim];
int pz;
inline void cit (int &x)
{
	x = 0;
	while (vec[pz] < '0' || vec[pz] > '9')
		if (++pz == dim) fread (vec, 1, dim, stdin), pz = 0;
	while (vec[pz] >= '0' && vec[pz] <= '9') {
		x = x * 10 + vec[pz] - '0';
		if (++pz == dim) fread (vec, 1, dim, stdin), pz = 0;
	}
}
int main ()
{


	freopen ("lca.in", "r", stdin);
	freopen ("lca.out", "w", stdout);

	//scanf ("%d %d\n", &N, &Q);	
	cit (N); cit (Q);
	
	int i, x, j, pw;
	
	for (i = 2; i <= N; i++) {
	//	scanf ("%d", &x);
		cit (x);
		G[x].push_back (i);
	}

	DFS (1, 0);
/*	for (i = 1; i <= p; i++)
		printf ("%d ", E[i]);
	printf ("\n");
	for (i = 1; i <= p; i++)
		printf ("%d ", L[i]);
*/	
	for (i = 1; i <= p; i++) {
		
		rmq[0][i] = i;
	}
	
	for (j = 1; (1 << j) <= p; j++) 
		for (i = 1, pw = 1 << (j - 1); i + pw <= p; i++)
			if (L[rmq[j - 1][i]] < L[rmq[j - 1][i + pw]]) {
				rmq[j][i] = rmq[j - 1][i];
			} else {
				rmq[j][i] = rmq[j - 1][i + pw];
			}
	
	for (i = 2; i <= p; i++)
		lg[i] = lg[i >> 1] + 1;
	
	int y, lgg;

	for (; Q != 0; Q--) {
//		scanf ("%d %d\n", &x, &y);
		cit (x); cit (y);		
		if (app[x] > app[y]) swap (x, y);
		x = app[x];
		y = app[y];
		lgg = lg[y - x + 1];
		
	//	printf ("%d %d %d\n", x, y, lgg);
		if (L[rmq[lgg][x]] > L[rmq[lgg][x + (y - x + 1) - (1 << lgg)]]) 
			printf ("%d\n", E[rmq[lgg][x + (y - x + 1) - (1 << lgg)]]);
		else printf ("%d\n", E[rmq[lgg][x]]);
	}

	return 0;
}