Cod sursa(job #812826)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 14 noiembrie 2012 15:51:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.11 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream fi ("lca.in");
ofstream fo ("lca.out");

const int dim = 200005;
int N, M, E[18][dim], P2[dim], Pr[dim>>1], L[dim>>1];
vector <int> F[dim>>1];

void cit ()
{
	fi >> N >> M;
	for (int i = 2, t; i <= N; i++)
	{
		fi >> t;
		F[t].push_back (i);
	}
}

void dfs (int n, int k)
{
	L[n] = k;
	E[0][++E[0][0]] = n;
	Pr[n] = E[0][0];
	for (int i = 0; i < F[n].size(); i++)
	{
		dfs (F[n][i], k + 1);
		E[0][++E[0][0]] = n;
	}	 
}

void prp ()
{
	int k, i, p, a, b;
	for (i = 2; i <= E[0][0]; i++)
		P2[i] = P2[i>>1] + 1;
	for (k = 1; 1<<k <= E[0][0]; k++)
	{
		p = 1<<k;
		for (i = 1; i+p-1 <= E[0][0]; i++)
		{
			a = E[k-1][i];
			b = E[k-1][i+(p>>1)];
			if (L[a] < L[b])
				E[k][i] = a;
			else
				E[k][i] = b;
		}
	}
}

int query (int a, int b)
{
	int k = P2[b - a + 1];
	int p = 1 << k;
	return min (E[k][a], E[k][b-p+1]);
}

int main ()
{
	int a, b;
	cit ();
	dfs (1, 1);
	prp ();
	while (M--)
	{
		fi >> a >> b;
		fo << query (min (Pr[a], Pr[b]), max (Pr[a], Pr[b])) << '\n';
	}
	return 0;
}