Cod sursa(job #1912633)

Utilizator horiainfoTurcuman Horia horiainfo Data 8 martie 2017 09:56:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <stack>

#define ll long long
#define N 100002
using namespace std;

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

struct Nod { int level, firstPos; vector<int> v; };

int v[N * 3];
int rmq[20][N * 3];

Nod node[N];

void Euler(int nod, int level)
{
	node[nod].firstPos = ++v[0];
	node[nod].level = level;
	v[v[0]] = nod;

	for (int i = 0; i < node[nod].v.size(); i++)
		if (!node[node[nod].v[i]].firstPos)
		{
			Euler(node[nod].v[i], level + 1);
			v[++v[0]] = nod;
		}
}

void CreateRMQ()
{
	for (int j = 1; j <= v[0]; j++)
		rmq[0][j] = v[j];

	for (int i = 1, pow = 2; pow <= v[0]; i++, pow <<= 1)
	{
		for (int j = 1; j <= v[0] - pow + 1; j++)
			if (node[rmq[i - 1][j]].level < node[rmq[i - 1][j + pow / 2]].level)
				rmq[i][j] = rmq[i - 1][j];
			else
				rmq[i][j] = rmq[i - 1][j + pow / 2];
	}
}

int querry(int st, int dr)
{
	if (st > dr)
		swap(st, dr);

	int pow = 0;
	while (1 << pow <= dr - st + 1)
		pow++;
	pow--;

	if (node[rmq[pow][st]].level < node[rmq[pow][dr - (1 << pow) + 1]].level)
		return rmq[pow][st];
	else
		return rmq[pow][dr - (1 << pow) + 1];
}

int main()
{
	int n, m, n1, n2, nod;

	fin >> n >> m;
	for (int i = 2; i <= n; i++)
	{
		fin >> nod;
		node[nod].v.push_back(i);
	}

	Euler(1, 1);
	CreateRMQ();

	for (int i = 1; i <= m; i++)
	{
		fin >> n1 >> n2;
		fout << querry(node[n1].firstPos, node[n2].firstPos) << '\n';
	}
	return 0;
}