Cod sursa(job #469724)

Utilizator ooctavTuchila Octavian ooctav Data 8 iulie 2010 18:03:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;

const int NMAX = 100005;
const int NRMAX = 500005;
const int LGMAX = 19;

int N, M;
int rmq[LGMAX][NRMAX];
vector<int> Urmasi[NMAX];
int NR;
int euler[NRMAX];
int nivel[NRMAX];
int aparitie[NMAX];
int lg[NRMAX];

void write()
{
	/*for(int i = 1 ; i <= NR ; i++)
		printf("%d ", i);
	printf("\n");*/
	for(int i = 1 ; i <= NR ; i++)
		printf("%d ", euler[i]);
	printf("\n");
	for(int i = 1 ; i <= NR ; i++)
		printf("%d ", nivel[i]);
	printf("\n");
	for(int i = 1 ; i <= N ; i++)
		printf("%d ", aparitie[i]);
	printf("\n\n\n");
	for(int i = 1 ; (1<<i) <= NR ; i++)
	{
		for(int j = 1 ; j + (1<<i) - 1 <= NR; j++)
			printf("%d ", rmq[i][j]);
		printf("\n");
	}
	printf("\n\n\n");
}

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

void dfs(int nod, int level)
{
	euler[++NR] = nod;
	nivel[NR] = level;
	aparitie[nod] = NR;
	
	for(vector<int> :: iterator it = Urmasi[nod].begin() ; it != Urmasi[nod].end() ; it++)
	{
		dfs(*it, level + 1);
		euler[++NR] = nod;
		nivel[NR] = level;
	}
}

void dinamica()
{
	for(int i = 2 ; i <= NR ; i++)
		lg[i] = lg[i / 2] + 1;
	
	for(int j = 1 ; j <= NR ; j++)
		rmq[0][j] = j;
	
	for(int i = 1 ; (1<<i) < NR ; i++)
		for(int j = 1 ; j + (1<<i) - 1 <= NR; j++)
			if(nivel[rmq[i - 1][j]] < nivel[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))];
}

void apeluri()
{
	int x, y;
	int log;
	for(int i = 1 ; i <= M ; i++)
	{
		scanf("%d%d", &x, &y);
		x = aparitie[x];
		y = aparitie[y];
		if(x > y)
			swap(x, y);
		log = lg[y - x + 1];
		int REZ;
		if(nivel[rmq[log][x]] < nivel[rmq[log][y - (1<<log) + 1]])
			REZ = rmq[log][x];
		else
			REZ = rmq[log][y - (1<<log) + 1];
		printf("%d\n", euler[REZ]);
	}
}

int main()
{
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	
	citi();
	dfs(1, 1);
	dinamica();
	//write();
	apeluri();
	
	return 0;
}