Cod sursa(job #2234732)

Utilizator vvvictorvictor vvvictor Data 26 august 2018 00:05:11
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <bits/stdc++.h>
using namespace std;

#define MAX_N 100001
#define MAX_SIZE 200001
#define MAX_RMQ 400001
#define MAX_LOG 18

int idx;
int n;
int lg[MAX_SIZE];

int M[MAX_RMQ][MAX_LOG], H[MAX_N], E[MAX_SIZE], L[MAX_SIZE];
vector<vector<int>> g(MAX_N);

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;

	auto log_lim = (int)log2((double)idx);

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

	for (int j = 1; j <= log_lim; j++)
		for (int i = 0; i + (1 << j) - 1 < idx; 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;
	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);
	}

	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;
}