Cod sursa(job #3259019)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 24 noiembrie 2024 18:35:52
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.35 kb
#include <bits/stdc++.h>
using namespace std;

const int kNil = -1;
const int kLog = 18;
using vai = vector<array<int, kLog>>;
using vi = vector<int>;
using vvi = vector<vector<int>>;

struct lca_bl {
	int n;
	vi tin, tout;
	vai up;
	int t;
	lca_bl() {}
	lca_bl(const vvi &adj, int root) : n(adj.size()), tin(n), tout(n), up(n), t(0) {
		up[root][0] = kNil;
		dfs(adj, root, kNil);
	}
	void dfs(const vvi &adj, int u, int v) {
		tin[u] = t++;
		for(int i = 1; i < kLog; i++) {
			if(up[u][i - 1] != kNil) {
				up[u][i] = up[up[u][i - 1]][i - 1];
			} else {
				up[u][i] = kNil;
			}
		}
		for(const auto &it : adj[u]) if(it != up[u][0]) {
			up[it][0] = u;
			dfs(adj, it, u);
		}
		tout[u] = t++;
	}
	bool upper(int u, int v) {
		return tin[u] <= tin[v] && tin[v] < tout[u];
	}
	int lca(int u, int v) {
		if(upper(u, v)) {
			return u;
		} else if(upper(v, u)) {
			return v;
		} else {
			for(int i = kLog - 1; i >= 0; i--) {
				if(up[u][i] != kNil && !upper(up[u][i], v)) {
					u = up[u][i];
				}
			}
			return up[u][0];
		}
	}
};



int main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	int n, q;
	cin >> n >> q;
	vector<vector<int>> adj(n);
	for(int i = 1; i < n; i++) {
		int p;
		cin >> p;
		p--;
		adj[p].emplace_back(i);
	}
	lca_bl ds(adj, 0);
	for(int i = 0; i < q; i++) {
		int u, v;
		cin >> u >> v;
		u--; v--;
		cout << ds.lca(u, v) + 1 << '\n';
	}
	return 0;
}