Cod sursa(job #2250836)

Utilizator aurelionutAurel Popa aurelionut Data 30 septembrie 2018 18:48:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const int NMAX = 1e5 + 5;
int n, q;
vector <int> graph[NMAX];
int h[NMAX], pos[NMAX];
int rmq[2 * NMAX][20], lg[2 * NMAX];
int euler[2 * NMAX], len;

void DFS(int node, int father)
{
	h[node] = h[father] + 1;
	euler[++len] = node;
	pos[node] = len;
	for (auto i : graph[node])
	{
		DFS(i, node);
		euler[++len] = node;
	}
}

void BuildRMQ()
{
	for (int i = 2;i <= len;++i)
		lg[i] = lg[i / 2] + 1;
	for (int i = 1;i <= len;++i)
		rmq[i][0] = i;
	int a, b;
	for (int p = 1;(1 << p) <= len;++p)
		for (int i = 1;i + (1 << p) - 1 <= len;++i)
		{
			a = rmq[i][p - 1];
			b = rmq[i + (1 << (p - 1))][p - 1];
			rmq[i][p] = (h[euler[a]] < h[euler[b]] ? a : b);
		}
}

inline int Query(int x, int y)
{
	x = pos[x];
	y = pos[y];
	if (x > y)
		swap(x, y);
	int p = lg[y - x + 1];
	int a = euler[rmq[x][p]];
	int b = euler[rmq[y - (1 << p) + 1][p]];
	return (h[a] < h[b] ? a : b);
}

int main()
{
	ifstream fin("lca.in");
	ofstream fout("lca.out");
	fin >> n >> q;
	int x, y;
	for (int i = 2;i <= n;++i)
	{
		fin >> x;
		graph[x].push_back(i);
	}
	DFS(1, 0);
	BuildRMQ();
	for (int i = 1;i <= q;++i)
	{
		fin >> x >> y;
		fout << Query(x, y) << "\n";
	}
	fin.close();
	fout.close();
	return 0;
}