1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include <algorithm> #include <stack>
#include <SparseTable>
class LCA { std::vector<int> dfn, nfd; SparseTable<int> st;
public: LCA() = default; LCA(const LCA&) = default; LCA(LCA&&) = default; LCA& operator=(const LCA&) = default; LCA& operator=(LCA&&) = default; LCA(const std::vector<std::vector<int>>& G, int root) { int N = static_cast<int>(G.size()); dfn.resize(N), nfd.resize(N); std::vector<int> parent(N, root); std::stack<int> S({root}); for (int cnt = -1, u; !S.empty();) { u = S.top(), S.pop(); if (cnt != -1) nfd[cnt] = parent[u]; dfn[u] = ++cnt; for (int v : G[u]) { if (v == parent[u]) continue; parent[v] = u, S.push(v); } } std::vector<int> data(N); for (int i = 0; i < N; ++i) data[i] = dfn[nfd[i]]; st = SparseTable<int>(std::move(data), [](int a, int b) { return std::min(a, b); }); } int operator()(int a, int b) { if (a == b) return a; auto [l, r] = std::minmax(dfn[a], dfn[b]); return nfd[st.get(l, r)]; } };
|