Cod sursa(job #2234719)

Utilizator vvvictorvictor vvvictor Data 25 august 2018 23:38:39
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>
using namespace std;
#define MAX_SIZE 200001

vector<int> H, E, L;
int idx;
int n;
int lg[MAX_SIZE];

vector<vector<int>> M;
vector<vector<int>> g;

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

void dfs(int u, int par, int depth)
{
	H[u] = idx;
	E[idx] = u;
	L[idx++] = depth;

	for (int &v : g[u])
	{
		if (v == par)
			continue;

		dfs(v, u, depth + 1);

		L[idx] = depth;
		E[idx++] = u;
	}
}

inline void make_sparse()
{
	for (register int i = 2; i <= idx; ++i)
		lg[i] = lg[i >> 1] + 1;

	int cols = floor(log2(L.size())) + 1;
	M.assign(L.size() + 1, vector<int> (cols, 0));

	int N = L.size();

	for (int i = 0; i < N; i++)
		M[i][0] = i;

	for (int j = 1; j < cols; j++)
		for (int i = 0; i + (1 << j) - 1 < N; i++)
			M[i][j] = L[M[i][j - 1]] <= L[M[i + (1 << (j - 1))][j - 1]] ? M[i][j - 1] : M[i + (1 << (j - 1))][j - 1]; 
}

inline int lca_rmq(int u, int v)
{
	u = H[u];
	v = H[v];

	if (u > v)
		swap(u, v);

	int k = lg[v - u + 1];
	int lca = L[M[u][k]] <= L[M[v - (1 << k) + 1][k]] ? M[u][k] : M[v - (1 << k) + 1][k];

	return E[lca];
}

int main()
{
	ios_base::sync_with_stdio(false);
	int m;
	fin >> n >> m;

	g.assign(n, vector<int> ());
	for (int i = 0; i < n - 1; i++)
	{
		int u;
		fin >> u;
		--u;

		g[u].push_back(i + 1);
		g[i + 1].push_back(u);
	}

	H.assign(n, -1);
	E.assign(2 * n, -1);
	L.assign(2 * n, - 1);

	dfs(0, -1, 0);
	make_sparse();

	for (int i = 0; i < m; i++)
	{
		int u, v;
		fin >> u >> v;
		--u, --v;
		fout << lca_rmq(u, v) + 1 << endl;
	}

	return 0;
}