Cod sursa(job #2084874)

Utilizator WebDesignbyTMGhiorghiu Ioan-Viorel WebDesignbyTM Data 9 decembrie 2017 12:31:18
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.17 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], ps[DM], nvl[DM], lg[DM];
vector <int> v[DM];

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

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

	//fac parcurgerea euler
	nvl[1] = -1;
	dfs(1, 1);

	//calculez rmq
	for (int i = 2; i <= rmq[0][0]; ++i)
		lg[i] = lg[i/2] + 1;
	--rmq[0][0];
	for (int i = 1; (1<<i) - 1 <= rmq[0][0]; ++i)
	{
		rmq[i][0] = rmq[0][0] - (1<<i) + 1;
		for (int x = 1; x + (1<<i) - 1 <= rmq[0][0]; ++x)
			if (nvl[rmq[i-1][x]] < nvl[rmq[i-1][x+(1<<(i-1))]])
				rmq[i][x] = rmq[i-1][x];
			else
				rmq[i][x] = rmq[i-1][x+(1<<(i-1))];
	}

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