Cod sursa(job #3224867)

Utilizator leelcheeseCiovnicu Denis leelcheese Data 16 aprilie 2024 13:30:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <bits/stdc++.h>
#include <unordered_map>
#define nmax 100007
#define MOD 9901
#define INF 2012345678
#define ll long long
using namespace std;
//#define fin cin
//#define fout cout

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

int n, m;
vector <int> L[nmax];
int euler[2 * nmax], niv[2 * nmax], P[2 * nmax];
int e[2 * nmax], rmq[18][2 * nmax];

void Euler(int node, int level)
{
	euler[++m] = node;
	niv[m] = level;
	P[node] = m;
	for (int i : L[node])
	{
		Euler(i, level + 1);
		euler[++m] = node;
		niv[m] = level;
	}
}

void MakeE()
{
	for (int i = 2; i <= m; i++)
		e[i] = e[i / 2] + 1;
}

void RMQLCA()
{
	int i, j, x, y, lg;
	for (i = 1; i <= m; i++)
		rmq[0][i] = i;

	for (i = 1; i <= e[m]; i++)
	{
		lg = (1 << i);
		for (j = 1; j <= m - lg + 1; j++)
		{
			x = rmq[i - 1][j];
			y = rmq[i - 1][j + lg / 2];
			if (niv[x] <= niv[y])
				rmq[i][j] = x;
			else
				rmq[i][j] = y;
		}
	}
}

int main()
{
	int i, j, x, y, Q, expo, lg;
	fin >> n >> Q;
	for (i = 2; i <= n; i++)
	{
		fin >> x;
		L[x].push_back(i);
	}

	Euler(1, 1);
	MakeE();
	RMQLCA();

	while (Q--)
	{
		fin >> i >> j;
		i = P[i];
		j = P[j];
		if (i > j)
			swap(i, j);

		expo = e[j - i + 1];
		lg = (1 << expo);
		i = rmq[expo][i];
		j = rmq[expo][j - lg + 1];

		if (niv[i] <= niv[j])
			x = i;
		else
			x = j;

		fout << euler[x] << "\n";
	}
	fout.close();
	fin.close();
	return 0;
}