Cod sursa(job #2544713)

Utilizator radustn92Radu Stancu radustn92 Data 12 februarie 2020 13:18:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
const int NMAX = 100505;
const int LMAX = (1 << 18);
const int LGMAX = 19;
int N, M;
vector<int> G[NMAX];
int euler[LMAX], firstEuler[NMAX], depth[NMAX], eulerIdx;
int lg[LMAX], lowestDepthRange[LGMAX][LMAX];
bool visited[NMAX];

void read() {
	cin >> N >> M;
	int x;
	for (int node = 2; node <= N; node++) {
		cin >> x;
		G[x].push_back(node);
		G[node].push_back(x);
	}
}

void dfs(int node) {
	visited[node] = true;
	euler[++eulerIdx] = node;
	firstEuler[node] = eulerIdx;
	for (auto neighbour : G[node]) {
		if (!visited[neighbour]) {
			depth[neighbour] = depth[node] + 1;
			dfs(neighbour);
			euler[++eulerIdx] = node;
		}
	}
}

inline int lowerDepth(int node1, int node2) {
	return depth[node1] < depth[node2] ? node1 : node2;
}

void buildRMQ() {
	for (int i = 2; i <= eulerIdx; i++) {
		lg[i] = lg[i >> 1] + 1;
	}
	for (int posEuler = 1; posEuler <= eulerIdx; posEuler++) {
		lowestDepthRange[0][posEuler] = euler[posEuler];
	}

	for (int pow2Idx = 1; (1 << pow2Idx) <= eulerIdx; pow2Idx++) {
		int currentLength = 1 << pow2Idx;
		int prevLength = 1 << (pow2Idx - 1);
		for (int start = 1; start <= eulerIdx - currentLength + 1; start++) {
			lowestDepthRange[pow2Idx][start] = lowerDepth(
				lowestDepthRange[pow2Idx - 1][start], lowestDepthRange[pow2Idx - 1][start + prevLength]);
		}
	}
}

int findNodeLowestDepth(int from, int to) {
	if (from > to) {
		swap(from, to);
	}

	int pow2Idx = lg[to - from + 1];
	return lowerDepth(
		lowestDepthRange[pow2Idx][from], lowestDepthRange[pow2Idx][to - (1 << pow2Idx) + 1]);
}

void solve() {
	dfs(1);
	buildRMQ();

	int x, y;
	for (int queryIdx = 0; queryIdx < M; queryIdx++) {
		cin >> x >> y;
		cout << findNodeLowestDepth(firstEuler[x], firstEuler[y]) << "\n";
	}
}

int main() {
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}