Cod sursa(job #1654792)

Utilizator vladttturcuman vlad vladtt Data 17 martie 2016 14:52:55
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
// Range Minimum Query.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <cmath>
#include <vector>

#define NMAX 100100
#define nMAX 1000100
#define LogMAX 20
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

struct Nod {
	int nod, lvl;
	Nod(int n, int l)
	{
		nod = n;
		lvl = l;
	}
	Nod()
	{

	}

	bool operator< (const Nod a) const
	{
		return lvl <= a.lvl;
	}
};

int n, m, i, x, y, st, p;

vector<int> ch[NMAX];

int first[NMAX];

Nod _rmq[nMAX][LogMAX];

Nod min(Nod a, Nod b)
{
	return a < b ? a : b;
}

void CreateMatrix()
{
	int LogMx = log2(n);


	for (int j = 1; j <= LogMx; j++)
	{
		x = (1 << j);
		for (i = 1; i + x - 1 <= n; i++)
			_rmq[i][j] = min(_rmq[i][j - 1], _rmq[i + x / 2][j - 1]);
	}

}

Nod rmq(int in, int sf)
{
	int diff = sf - in + 1;
	int lg = log2(diff);
	return min(_rmq[in][lg], _rmq[sf - (1 << lg) + 1][lg]);
}

void Euler(int nod,int lvl)
{
	_rmq[++n][0] = *(new Nod(nod,lvl));
	if (!first[nod])
		first[nod] = n;

	for (int i = 0; i < ch[nod].size(); i++)
	{
		Euler(ch[nod][i],lvl+1);
		_rmq[++n][0] = *(new Nod(nod, lvl));
	}
}

int main()
{

	fin >> n;
	fin >> m;


	for (i = 2; i <= n; i++)
	{
		fin >> p;
		if (p != i)
			ch[p].push_back(i);
		else
			st = i;
	}

	n = 0;

	Euler(1,1);



	CreateMatrix();

	for (i = 1; i <= m; i++)
	{
		fin >> x >> y;
		fout << (rmq(first[x],first[y])).nod << '\n';
	}

	return 0;
}