#include #include #include #include class TreeAncestor { private: std::vector> predecessor; std::vector depth; public: TreeAncestor(std::vector>& edges) { int n = edges.size() + 1; int m = bit_width((unsigned)n); predecessor.resize(n, std::vector(m, -1)); depth.resize(n, 0); std::vector> graph(n); for (const auto& [u, v] : edges) { graph[u].emplace_back(v); graph[v].emplace_back(u); } auto dfs = [&](auto&& dfs, int x, int fa) -> void { predecessor[x][0] = fa; for (auto y : graph[x]) { if (y != fa) { depth[y] = depth[x] + 1; dfs(dfs, y, x); } } }; dfs(dfs, 0, -1); for (int i = 1; i < m; i++) { for (int x = 0; x < n; x++) { if (int p = predecessor[x][i - 1]; p != -1) { predecessor[x][i] = predecessor[p][i - 1]; } } } } int getKthAncestor(int node, int k) { //for (int i = 0; i < bit_width((unsigned)k) && node != -1; i++) { // if (k >> i & 1) { // node = predecessor[node][i]; // } //} for (; k && node != -1; k &= k - 1) { node = predecessor[node][countr_zero(unsigned(k))]; } return node; } int getLowestCommonAncestor(int u, int v) { if (depth[u] > depth[v]) { std::swap(u, v); } for (int k = depth[v] - depth[u]; k; k &= k - 1) { v = predecessor[v][countr_zero(unsigned(k))]; } if (u != v) { for (int i = predecessor[u].size() -1; i >= 0; i--) { int pu = predecessor[u][i], pv = predecessor[v][i]; if (pu != pv) { u = pu, v = pv; } } } return predecessor[u][0]; } };