Cod sursa(job #2249530)

Utilizator aurelionutAurel Popa aurelionut Data 30 septembrie 2018 01:12:47
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include <fstream>
#include <vector>

using namespace std;

const int NMAX = 1e5;
int rmq[22][2 * NMAX];
int E[2 * NMAX], k;
int niv[2 * NMAX], poz[NMAX];
int a[NMAX], n, m;
int lg[NMAX];
vector <int> L[NMAX];

void Euler(int nod, int nivel)
{
	E[++k] = nod;
	niv[k] = nivel;
	poz[nod] = k;
	for (auto i : L[nod])
	{
		Euler(i, nivel + 1);
		E[++k] = nod;
		niv[k] = nivel;
	}
}

int main()
{
	ifstream fin("lca.in");
	ofstream fout("lca.out");
	fin >> n >> m;
	int x, y;
	for (int i = 2;i <= n;++i)
	{
		fin >> x;
		L[x].push_back(i);
	}
	Euler(1, 1);
	for (int i = 1;i <= k;++i)
		rmq[0][i] = i;
	///fasim lg
	lg[1] = 0;
	for (int i = 2;i <= k;++i)
		lg[i] = lg[i >> 1] + 1;
	//int N = lg[k];
	///rmq;
	int N = lg[k];
	for (int p = 1;p <= N;++p)
		for (int j = 1;j + (1 << p) - 1 <= k;++j)
		{
			x = niv[rmq[p - 1][j]];
			y = niv[rmq[p - 1][j + (1 << (p - 1))]];
			if (x < y)
				rmq[p][j] = rmq[p - 1][j];
			else
				rmq[p][j] = rmq[p - 1][j + (1 << (p - 1))];
		}
	///query
	int p;
	for (int i = 1;i <= m;++i)
	{
		fin >> x >> y;
		x = poz[x];
		y = poz[y];
		if (x > y)
			swap(x, y);
		p = lg[y - x + 1];
		x = rmq[p][x];
		y = rmq[p][y - (1 << p) + 1];
		if (niv[x] < niv[y])
			fout << E[x] << "\n";
		else
			fout << E[y] << "\n";
	}
	fin.close();
	fout.close();
	return 0;
}