Cod sursa(job #582700)

Utilizator skullLepadat Mihai-Alexandru skull Data 15 aprilie 2011 18:47:50
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define nmax 100005

vector<int> G[nmax];
int arb[8*nmax], eul[2*nmax], nivel[2*nmax], poz[nmax];
int N, M, K, rpoz, Nivmin;

void citire ()
{
	int i, x;
	scanf("%d%d", &N, &M);
	for (i = 2; i <= N; ++i)
	{
		scanf("%d", &x);
		G[x].push_back(i);
	}
}

void euler(int nod, int niv)
{
	int i, urm;
	eul[++K] = nod; nivel[K] = niv;
	if ( !poz[nod] ) poz[nod] = K;
	for (i = 0; i < G[nod].size (); ++i)
	{
		urm = G[nod][i];
		euler(urm, niv+1);
		eul[++K] = nod; nivel[K] = niv;
	}
}

void update(int ind, int st, int dr, int pz, int val)
{
	if (st == dr) { arb[ind] = val; return; }
	int mij = (st+dr) / 2;
	if (pz <= mij) update(2*ind, st, mij, pz, val);
		else update(2*ind+1, mij+1, dr, pz, val);
	if (nivel[arb[2*ind]] <= nivel[arb[2*ind+1]]) arb[ind] = arb[2*ind];
		else arb[ind] = arb[2*ind+1];
}

void cauta(int ind, int st, int dr, int a, int b)
{
	if (a <= st && dr <= b)
	{
		if (Nivmin > nivel[arb[ind]]) { Nivmin = nivel[arb[ind]]; rpoz = eul[arb[ind]]; }
		return;
	}
	int mij = (st+dr) / 2;
	if (a <= mij) cauta(2*ind, st, mij, a, b);
	if (mij < b) cauta(2*ind+1, mij+1, dr, a, b);
}

void solve ()
{
	int i, x, y;
	for (i = 1; i <= K; ++i) update(1, 1, K, i, i);
	while ( M-- )
	{
		Nivmin = nmax;
		scanf("%d%d", &x, &y);
		if ( x > y ) swap(x, y);
		cauta(1, 1, K, poz[x], poz[y]);
		printf("%d\n", rpoz);
	}
}

int main ()
{
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	citire ();
	euler (1, 0);
	solve ();
	return 0;
}