Cod sursa(job #3213051)

Utilizator leelcheeseCiovnicu Denis leelcheese Data 12 martie 2024 13:42:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <bits/stdc++.h>
#include <unordered_map>
#define nmax 100006
#define MOD 1999999973
#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;
int niv[2 * nmax], euler[2 * nmax], P[nmax];
int rmq[18][2 * nmax], e[2 * nmax];
vector <int> L[nmax];

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

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

void RMQLCA()
{
	int i, j, lg, x, y;
	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, x, y, Q, expo, lg, A, B;
	fin >> n >> Q;
	for (i = 2; i <= n; i++)
	{
		fin >> x;
		L[x].push_back(i);
	}

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

	while (Q--)
	{
		fin >> x >> y;
		x = P[x];
		y = P[y];
		if (x > y) // luam minim x si maxim y mereu
			swap(x, y);
		expo = e[y - x + 1];
		lg = (1 << expo);
		A = rmq[expo][x];
		B = rmq[expo][y - lg + 1];
		if (niv[A] <= niv[B])
			x = A;
		else
			x = B;
		fout << euler[x] << "\n";
	}

	fin.close();
	fout.close();
	return 0;
}