Cod sursa(job #2954265)

Utilizator stefanchpStefan Chiper stefanchp Data 13 decembrie 2022 18:44:09
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <iostream>
#include <vector>
#include <stack>
#include <fstream>
#include <algorithm>
#include <cmath>
#define N 100000
using namespace std;

int a[2 * N + 5], M[N + 5][19];
int n, q;
int t[N + 5], niv[N + 5];
bool viz[N + 5];
int f[N + 5];
int k;
vector<int> g[N];

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

void dfs(int x, int nivel)
{
	viz[x] = 1;
	a[++k] = x; 
	niv[k] = nivel;
	for (int i = 0; i < g[x].size(); i++)
		if (!viz[g[x][i]])
		{
			dfs(g[x][i], nivel + 1);
			a[++k] = x;
			niv[k] = nivel;
		}
}

void rmq();

void citire()
{
	fin >> n >> q;
	for (int i = 2; i <= n; i++)
	{
		fin >> t[i];
		g[t[i]].push_back(i);
		g[i].push_back(t[i]);
	}
	dfs(1, 1);
	/*for (int i = 1; i <= k; i++)
		cout << a[i] << "  ";
	cout << '\n';
	for (int i = 1; i <= k; i++)
		cout << niv[i] << "  ";*/
	
	///prima aparitie
	for (int i = 1; i <= k; i++)
		if (!f[a[i]])
			f[a[i]] = i;
	
	rmq();
	int x, y;
	for (int i = 1; i <= q; i++)
	{
		fin >> x >> y;
		int dif = abs(f[y] - f[x]) + 1;
		int aux1 = min(f[y], f[x]);
		int aux2 = max(f[y], f[x]);
		int log2_dif = log2(dif);
		fout << min(a[M[aux1][log2_dif]], a[M[aux2 - (1 << log2_dif) + 1][log2_dif]]) << '\n';

	}
}
void rmq()
{
	for (int i = 1; i <= k; i++)
		M[i][0] = i;
	
	int  log2_k = log2(k);
	for (int j = 1; j <= log2_k; j++)
		for (int i = 1; i + (1 << j) - 1 <= k && i <= k; i++)
		{
			if (niv[M[i][j - 1]] < niv[M[i + (1 << (j - 1))][j - 1]])
				M[i][j] = M[i][j - 1];
			else
				M[i][j] = M[i + (1 << (j - 1))][j - 1];
		}
}

int main()
{
	citire();
	rmq();
	return 0;
}