Cod sursa(job #2462540)

Utilizator vladvlad00Vlad Teodorescu vladvlad00 Data 27 septembrie 2019 15:47:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <vector>
#define pb push_back

using namespace std;

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

void euler(int x);
void createRMQ();
int queryRMQ(int x, int y);
int LCA(int x, int y);

int n, m, nivel, poz, prima[100005], uz[100005], niv[200005], nod[200005], RMQ[20][200005];
vector<int> L[100005];

int main()
{
	int i, x, y;

	fin >> n >> m;
	for (i = 2; i <= n; i++)
	{
		fin >> x;
		L[x].pb(i);
		L[i].pb(x);
	}
	euler(1);
	createRMQ();
	for (i = 1; i <= m; i++)
	{
		fin >> x >> y;
		fout << LCA(x, y) << '\n';
	}
	return 0;
}

void euler(int x)
{
	int i;

	uz[x] = 1;
	prima[x] = poz + 1;
	for (i = 0; i < L[x].size(); i++)
		if (!uz[L[x][i]])
		{
			uz[L[x][i]] = 1;
			nod[++poz] = x;
			niv[poz] = nivel;
			nivel++;
			euler(L[x][i]);
			nivel--;
		}
	nod[++poz] = x;
	niv[poz] = nivel;
}

void createRMQ()
{
	int i, j, k, p2;

	for (i = 1; i <= poz; i++)
		RMQ[0][i] = i;
	p2 = 1;
	k = 0;
	while ((p2 << 1) < poz)
	{
		p2 <<= 1;
		k++;
	}
	for (j = 1, p2 = 2; j <= k; j++, p2 <<= 1)
		for (i = 1; i + p2 - 1 <= poz; i++)
		{
			if (niv[RMQ[j - 1][i]] < niv[RMQ[j - 1][i + (p2 >> 1)]])
				RMQ[j][i] = RMQ[j - 1][i];
			else RMQ[j][i] = RMQ[j - 1][i + (p2 >> 1)];
		}
}

int queryRMQ(int x, int y)
{
	int p2 = 1, k=0;

	while (x + (p2<<1) <= y)
	{
		p2 <<= 1;
		k++;
	}
	if (niv[RMQ[k][x]] < niv[RMQ[k][y-p2+1]])
		return RMQ[k][x];
	return RMQ[k][y-p2+1];
}

int LCA(int x, int y)
{
	x = prima[x];
	y = prima[y];
	if (x > y)
		swap(x, y);
	int aux = queryRMQ(x, y);
	return nod[aux];
}