DuongNhi99

TOURIST - LCA (rmq O(1))

Jan 18th, 2022 (edited)
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.83 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using ll = long long;
  5.  
  6. const int maxN = 110;
  7. const int INF = 1e9 + 7;
  8.  
  9. int n, lg;
  10. vector<int> graph[maxN];
  11.  
  12. namespace LCA {
  13. #define MASK(i) (1LL << (i))
  14. #define MIN_HIGH(x, y) (high[x] < high[y] ? (x) : (y))
  15.  
  16. int high[maxN], pos[maxN];
  17. int nodes[maxN], cnt;
  18.  
  19. int rmq[maxN][25];
  20.  
  21. void DFS(int u, int p) {
  22.     nodes[++cnt] = u;
  23.     pos[u] = cnt;
  24.     for (int v : graph[u]) {
  25.         if (v == p) continue;
  26.  
  27.         high[v] = high[u] + 1;
  28.         DFS(v, u);
  29.         nodes[++cnt] = u;
  30.     }
  31. }
  32.  
  33. void build_LCA() {
  34.     DFS(1, 1);
  35.     for (int i = 1; i <= cnt; i++)
  36.         rmq[i][0] = nodes[i];
  37.  
  38.     for (int j = 1; j <= 25; j++)
  39.         for (int i = 1; i <= cnt - MASK(j) + 1; i++)
  40.             rmq[i][j] = MIN_HIGH(rmq[i][j - 1], rmq[i + MASK(j - 1)][j - 1]);
  41. }
  42.  
  43. int find_LCA(int u, int v) {
  44.     int l = pos[u];
  45.     int r = pos[v];
  46.     if (l > r) swap(l, r);
  47.  
  48.     int k = 31 - __builtin_clz(r - l + 1);
  49.     return MIN_HIGH(rmq[l][k], rmq[r - MASK(k) + 1][k]);
  50. }
  51. } // namespace LCA
  52.  
  53. int main() {
  54. #ifdef LOCAL
  55.     freopen("in1.txt", "r", stdin);
  56. #else
  57.     freopen("TOURIST - LCA.inp", "r", stdin);
  58.     freopen("TOURIST - LCA.out", "w", stdout);
  59. #endif
  60.     ios_base::sync_with_stdio(false);
  61.     cin.tie(nullptr);
  62.  
  63.     cin >> n;
  64.     for (int i = 1; i <= n-1; ++i) {
  65.         int u, v; cin >> u >> v;
  66.         graph[u].push_back(v);
  67.         graph[v].push_back(u);
  68.     }
  69.  
  70.     LCA::build_LCA();
  71.  
  72.     ll ans = 0;
  73.     for (int u = 1; u <= n; ++u) {
  74.         for (int i = 2; i <= n/u; ++i) {
  75.             int v = u * i;
  76.             int t = LCA::find_LCA(u, v);
  77.  
  78.             int x1 = (LCA::high[u] - LCA::high[t]);
  79.             int x2 = (LCA::high[v] - LCA::high[t]);
  80.  
  81.             ans += x1 + x2 + 1;
  82.         }
  83.     }
  84.     cout << ans << '\n';
  85.  
  86.     return 0;
  87. }
  88.  
Add Comment
Please, Sign In to add comment