This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub ruthen71/rcpl
#include "icpc/lca.hpp"
#pragma once #include "icpc/template.hpp" // https://onlinejudge.u-aizu.ac.jp/problems/3329 struct LCA { V<int> dep; V<V<int>> par; int n, log; LCA(V<V<int>>& g, int root = 0) : n(int(g.size())), log(32 - __builtin_clz(g.size())) { dep.assign(n, 0); par.assign(log, V<int>(n)); auto dfs = [&](auto f, int c, int p) -> void { par[0][c] = p; for (auto& e : g[c]) { if (e == p) continue; dep[e] = dep[c] + 1; f(f, e, c); } }; dfs(dfs, root, -1); REP(k, log - 1) REP(v, n) par[k + 1][v] = (par[k][v] == -1 ? -1 : par[k][par[k][v]]); } int lca(int u, int v) { assert(int(dep.size()) == n); if (dep[u] > dep[v]) swap(u, v); REP(k, log) if ((dep[v] - dep[u]) >> k & 1) v = par[k][v]; if (u == v) return u; for (int k = log - 1; k >= 0; k--) { if (par[k][u] != par[k][v]) { u = par[k][u]; v = par[k][v]; } } return par[0][u]; } int level_ancestor(int u, int d) { assert(int(dep.size()) == n); if (dep[u] < d) return -1; REP(k, log) if (d >> k & 1) u = par[k][u]; return u; } int distance(int u, int v) { int p = lca(u, v); return dep[u] + dep[v] - 2 * dep[p]; } };
#line 2 "icpc/lca.hpp" #line 2 "icpc/template.hpp" #include <bits/stdc++.h> using namespace std; using ll = long long; #define REP(i, n) for (int i = 0; i < (n); i++) template <class T> using V = vector<T>; template <class T> ostream& operator<<(ostream& os, const V<T>& v) { os << "[ "; for (auto& vi : v) os << vi << ", "; return os << "]"; } #ifdef LOCAL #define show(x) cerr << __LINE__ << " : " << #x << " = " << x << endl; #else #define show(x) true #endif using uint = unsigned int; using ull = unsigned long long; // g++ -g -fsanitize=undefined,address -DLOCAL -std=gnu++17 #line 4 "icpc/lca.hpp" // https://onlinejudge.u-aizu.ac.jp/problems/3329 struct LCA { V<int> dep; V<V<int>> par; int n, log; LCA(V<V<int>>& g, int root = 0) : n(int(g.size())), log(32 - __builtin_clz(g.size())) { dep.assign(n, 0); par.assign(log, V<int>(n)); auto dfs = [&](auto f, int c, int p) -> void { par[0][c] = p; for (auto& e : g[c]) { if (e == p) continue; dep[e] = dep[c] + 1; f(f, e, c); } }; dfs(dfs, root, -1); REP(k, log - 1) REP(v, n) par[k + 1][v] = (par[k][v] == -1 ? -1 : par[k][par[k][v]]); } int lca(int u, int v) { assert(int(dep.size()) == n); if (dep[u] > dep[v]) swap(u, v); REP(k, log) if ((dep[v] - dep[u]) >> k & 1) v = par[k][v]; if (u == v) return u; for (int k = log - 1; k >= 0; k--) { if (par[k][u] != par[k][v]) { u = par[k][u]; v = par[k][v]; } } return par[0][u]; } int level_ancestor(int u, int d) { assert(int(dep.size()) == n); if (dep[u] < d) return -1; REP(k, log) if (d >> k & 1) u = par[k][u]; return u; } int distance(int u, int v) { int p = lca(u, v); return dep[u] + dep[v] - 2 * dep[p]; } };