Cod sursa(job #2085101)

Utilizator WebDesignbyTMGhiorghiu Ioan-Viorel WebDesignbyTM Data 9 decembrie 2017 18:14:34
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#define DM 100001
#include <fstream>
#include <vector>
using namespace std;

ifstream fi ("lca.in");
ofstream fo ("lca.out");
int n, m, a, b, rmq[18][DM], nvl[DM], lg[DM*4], ps[DM];
vector <int> v[DM], elr;//v - muchii; elr - reprezentare euler

void dfs(int nod, int p)
{
	nvl[nod] = nvl[p] + 1;
	elr.push_back(nod);
	for (auto i:v[nod])
		if (i != p)
			dfs(i, nod);
	elr.push_back(p);
}

int main()
{
	fi >> n >> m;
	for (int i = 2; i <= n; ++i)
	{
		fi >> a;
		v[a].push_back(i);
		v[i].push_back(a);
	}

	//parcurgere euler
	nvl[1] = -1;
	dfs(1, 1);
	elr.pop_back();

	//alcatuire rmq
	for (int i = 2; i <= elr.size(); ++i)
		lg[i] = lg[i/2] + 1;
	for (int i = 0; i < elr.size(); ++i)
	{
		rmq[0][i+1] = elr[i];
		if (!ps[elr[i]])
			ps[elr[i]] = i + 1;
	}
	for (int i = 1; (1<<i) - 1 <= elr.size(); ++i)
		for (int j = 1; j + (1<<i) - 1 <= elr.size(); ++j)
			if (nvl[rmq[i-1][j]] < nvl[rmq[i-1][j+(1<<(i-1))]])
				rmq[i][j] = rmq[i-1][j];
			else
				rmq[i][j] = rmq[i-1][j+(1<<(i-1))];

	//rezolvare querry-uri
	for (int i = 1; i <= m; ++i)
	{
		fi >> a >> b;
		a = ps[a];
		b = ps[b];
		if (a > b)
			swap(a, b);
		if (nvl[rmq[lg[b-a]][a]] < nvl[rmq[lg[b-a]][b-(1<<lg[b-a])+1]])
			fo << rmq[lg[b-a]][a] << '\n';
		else
			fo << rmq[lg[b-a]][b-(1<<lg[b-a])+1] << '\n';
	}
	return 0;
}