Cod sursa(job #3330739)

Utilizator herbiHreban Antoniu George herbi Data 21 decembrie 2025 17:14:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<pair<int, int>>euler;
vector<vector<int>>v;
vector<vector<int>>m;
vector<int>nivel;
vector<int>lg;
vector<int>indice_prima_aparitie;
int n, q;
int x, y, z, k;
void citire_graf()
{
	fin >> n >> q;
	v.resize(n + 1);
	indice_prima_aparitie.resize(n + 1);
	nivel.resize(n + 1);
	nivel[1] = 0;
	for (int i = 2; i <= n; i++)
	{
		fin >> x;
		v[x].push_back(i);
	}

}
void dfs_euler(int nod)
{
	euler.push_back({ nod, nivel[nod] });
	indice_prima_aparitie[nod] = euler.size() - 1;
	for (auto i : v[nod])
	{
		nivel[i] = nivel[nod] + 1;
		dfs_euler(i);
		euler.push_back({ nod,nivel[nod] });
	}
}
void afis_euler()
{
	for (auto i : euler)
		fout << i.first << " " << i.second << '\n';
	fout << '\n' << '\n';
	for (int i = 1; i <= n; i++)
		fout << indice_prima_aparitie[i] << " ";
}
int main()
{
	citire_graf();
	euler.push_back({ 0,0 });
	dfs_euler(1);
	n = (2 * n) - 1;
	lg.resize(n + 1);
	lg[1] = 0;
	for (int i = 2; i <= n; i++)
		lg[i] = lg[i / 2] + 1;
	m.resize(lg[n] + 1, vector<int>(n + 1));
	for (int i = 1; i <= n; i++)
		m[0][i] = i;

	for(int i=1;(1<<i)<=n;i++)
		for (int j = 1; j + (1 << i) <= n + 1; j++)
		{
			if (euler[m[i - 1][j]].second < euler[m[i - 1][j + (1 << (i - 1))]].second)
				m[i][j] = m[i - 1][j];
			else
				m[i][j] = m[i - 1][j + (1 << (i - 1))];
		}

	
	for (int i = 1; i <= q; i++)
	{
		fin >> x >> y;
		x = indice_prima_aparitie[x];
		y = indice_prima_aparitie[y];
		if (x > y)
			swap(x, y);
		k = lg[y - x + 1];
		if (euler[m[k][x]].second < euler[m[k][y - (1 << k) + 1]].second)
			fout << euler[m[k][x]].first;
		else
			fout << euler[m[k][y - (1 << k) + 1]].first;
		fout << '\n';
	}
	
	return 0;
}