Cod sursa(job #383597)

Utilizator ilincaSorescu Ilinca ilinca Data 17 ianuarie 2010 10:48:47
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.36 kb
#include <stdio.h>
#include <vector> 
#define nmax 100005
#define mmax 200005
#define lmax 20

using namespace std;

int n, m, w, d [nmax], p2 [nmax<<2], poz [nmax], r [lmax] [nmax<<2];
vector <int> fii [nmax];

void init ()
{
	p2 [1]=0;
	for (int i=2; i <= w; ++i) 	p2 [i] = p2 [i>>1]+1;
}

void euler (int nod)
{
	vector <int> :: iterator i;
	r [0] [++w]=nod;
	for (i=fii [nod].begin (); i != fii [nod].end (); ++i) 
	{
			d [*i]=d [nod]+1;
			euler (*i);
			r [0] [++w]=nod;
	}
}

void rmq ()
{
	int i, j, i1=p2 [w], i2;
	for (i=1; i <= i1; ++i) 
	{
		i2=w-p2 [i]+1;
		for (j=1; j <= i2; ++j) 
			if (d [r [i-1] [j]] < d [r [i-1] [j+(1<<(i-1))]]) 
				r [i] [j]=r [i-1] [j];
			else
				r [i] [j]=r [i-1] [j+(1<<(i-1))];
	}
}

void pozitie ()
{
	for (int i=1; i <= w; ++i) 
		if (poz [r [0] [i]] == 0) 
			poz [r [0] [i]]=i;
}

int main ()
{
	freopen ("lca.in", "r", stdin);
	freopen ("lca.out", "w", stdout);
	int i, a, b, k, x, aux, a2, b2;
	scanf ("%d%d", &n, &m);
	for (i=2; i <= n; ++i) 
	{
		scanf ("%d", &x);
		fii [x].push_back (i);
	}
	euler (1);
	init ();
	rmq ();
	pozitie ();
	for (i=1; i <= m; ++i) 
	{
		scanf ("%d%d", &a, &b);
		a2=poz [a];
		b2=poz [b];
		if (b2 < a2) 
		{
			aux=a2;
			a2=b2;
			b2=aux;
		}
		k=p2 [b2-a2+1];
		if (d [r [k] [a2]] < d [r [k] [b2-(1<<k)+1]]) 
			printf ("%d\n", r [k] [a2]);
		else
			printf ("%d\n", r [k] [b2-(1<<k)+1]);	
	}
	return 0;
}