Cod sursa(job #728784)

Utilizator Catah15Catalin Haidau Catah15 Data 28 martie 2012 23:00:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>

using namespace std;

#define maxN 100010
#define maxK 21
#define PB push_back

int Level[maxN], tata[maxN], Ap[maxN];
int Euler[maxN << 1], rmq[maxK][maxN << 1];
int Lg[maxN << 1];
vector <int> list[maxN];


void DFS (int nod)
{
	Euler[++ Euler[0]] = nod;
	Ap[nod] = Euler[0];
	
	for (unsigned int i = 0; i < list[nod].size(); ++ i)
	{
		int nod2 = list[nod][i];
		
		Level[nod2] = Level[nod] + 1;
		DFS (nod2);
		Euler[++ Euler[0]] = nod;
	}
}


void RMQ ()
{
	for (int i = 1; i <= Euler[0]; ++ i) rmq[0][i] = Euler[i];
	
	for (int i = 1; (1 << i) <= Euler[0]; ++ i) 
		for (int j = 1; j <= Euler[0] - (1 << i) + 1; ++ j) 
			if (Level[rmq[i - 1][j]] < Level[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))];
}


inline int LCA (int X, int Y)
{
	if (X > Y) swap (X, Y);
	
	int nrE = Y - X + 1;
	int K = Lg[nrE];
	
	if (Level[rmq[K][X]] < Level[rmq[K][X + nrE - (1 << K)]]) return rmq[K][X];
	else return rmq[K][X + nrE - (1 << K)];
}


int main()
{
	freopen ("lca.in", "r", stdin);
	freopen ("lca.out", "w", stdout);
	
	int N, M;
	
	scanf ("%d %d", &N, &M);
	
	for (int i = 2; i <= N; ++ i)
	{
		scanf ("%d", &tata[i]);
		list[tata[i]].PB (i);
	}
	
	DFS (1);
	RMQ ();

	for (int i = 2; i <= Euler[0]; ++ i) Lg[i] = Lg[i / 2] + 1;
	
	for (int i = 1, X, Y; i <= M; ++ i)
	{
		scanf ("%d %d", &X, &Y);
		printf ("%d\n", LCA (Ap[X], Ap[Y]));
	}
	
	return 0;
}