Advertisement
999ms

HLD

Oct 28th, 2019
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.86 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define all(x) (x).begin(), (x).end()
  3.  
  4. using namespace std;
  5. using ll = long long;
  6.  
  7. const int N = 100100;
  8.  
  9. vector<int> g[N];
  10. int depth[N];
  11. int tsize[N];
  12. int par[N][20];
  13. int hld[N];
  14. int inhld[N];
  15. int hldsz[N];
  16. int top[N];
  17.  
  18. struct SegmentTree {
  19.     vector<ll> t;
  20.     int n;
  21.     SegmentTree(int n = 0) : n(n) {
  22.         t.assign(n * 4, 0);
  23.     }
  24.     void Upd(int v, int tl, int tr, int i, int val) {
  25.         if (tl + 1 == tr) {
  26.             t[v] += val;
  27.         } else {
  28.             int tm = (tl + tr) / 2;
  29.             if (i < tm) {
  30.                 Upd(v * 2 + 1, tl, tm, i, val);
  31.             } else {
  32.                 Upd(v * 2 + 2, tm, tr, i, val);
  33.             }
  34.             t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
  35.         }
  36.     }
  37.     ll Get(int v, int tl, int tr, int l, int r) {
  38.         if (tl >= r || tr <= l) return 0;
  39.         if (tl >= l && tr <= r) return t[v];
  40.         int tm = (tl + tr) / 2;
  41.         return max(Get(v * 2 + 1, tl, tm, l, r), Get(v * 2 + 2, tm, tr, l, r));
  42.     }
  43. };
  44. vector<SegmentTree> t;
  45.  
  46. void Dfs(int from, int p, int h = 0) {
  47.     depth[from] = h;
  48.     par[from][0] = p;
  49.     tsize[from] = 1;
  50.     for (int i = 1; i < 20; i++) {
  51.         par[from][i] = par[par[from][i - 1]][i - 1];
  52.     }
  53.     for (int v : g[from]) {
  54.         if (v != p) {
  55.             Dfs(v, from, h + 1);
  56.             tsize[from] += tsize[v];
  57.         }
  58.     }
  59. }
  60.  
  61. void Build(int from, int p, int& index) {
  62.     hld[from] = index;
  63.     int itr = 0;
  64.     for (int v : g[from]) {
  65.         if (v != p) {
  66.             itr++;
  67.             index += itr > 1;
  68.             Build(v, from, index);
  69.         }
  70.     }
  71. }
  72.  
  73. void BuildHld(int n) {
  74.     Dfs(0, 0);
  75.     for (int i = 0; i < n; i++) {
  76.         sort(all(g[i]), [&] (int i, int j) { return tsize[i] > tsize[j];});
  77.     }
  78.     int sz = 0;
  79.     Build(0, 0, sz);
  80.     sz++;
  81.     vector<vector<int>> arr(sz);
  82.     for (int i = 0; i < n; i++) {
  83.         arr[hld[i]].push_back(i);
  84.     }
  85.     for (int i = 0; i < sz; i++) {
  86.         sort(all(arr[i]), [&] (int i, int j) { return depth[i] < depth[j]; });
  87.         for (int j = 0; j < arr[i].size(); j++) {
  88.             inhld[arr[i][j]] = j;
  89.         }
  90.         t.emplace_back(arr[i].size());
  91.         top[i] = arr[i][0];
  92.     }
  93. }
  94.  
  95. int lca(int a, int b) {
  96.     if (depth[a] < depth[b]) swap(a, b);
  97.     for (int i = 19; i >= 0; i--) {
  98.         if (depth[par[a][i]] >= depth[b]) {
  99.             a = par[a][i];
  100.         }
  101.     }
  102.     if (a == b) return a;
  103.     for (int i = 19; i >= 0; i--) {
  104.         if (par[a][i] != par[b][i]) {
  105.             a = par[a][i];
  106.             b = par[b][i];
  107.         }
  108.     }
  109.     return par[a][0];
  110. }
  111.  
  112. void Upd(int a, int val) {
  113.     auto& tree = t[hld[a]];
  114.     tree.Upd(0, 0, tree.n, inhld[a], val);
  115. }
  116.  
  117. ll Get(int a, int b) {
  118.     int c = lca(a, b);
  119.     ll ans = 0;
  120.     while (hld[a] != hld[c]) {
  121.         auto& tree = t[hld[a]];
  122.         ans = max(ans, tree.Get(0, 0, tree.n, 0, inhld[a] + 1));
  123.         a = par[top[hld[a]]][0];
  124.     }
  125.     while (hld[b] != hld[c]) {
  126.         auto& tree = t[hld[b]];
  127.         ans = max(ans, tree.Get(0, 0, tree.n, 0, inhld[b] + 1));
  128.         b = par[top[hld[b]]][0];
  129.     }
  130.     if (depth[a] > depth[b]) swap(a, b);
  131.     auto& tree = t[hld[a]];
  132.     ans = max(ans, tree.Get(0, 0, tree.n, inhld[a], inhld[b] + 1));
  133.     return ans;
  134. }
  135. int main() {
  136.     ios_base::sync_with_stdio(false);
  137.     cin.tie(nullptr);
  138.     cout.tie(nullptr);
  139.     int n;
  140.     cin >> n;
  141.     for (int i = 0; i + 1 < n; i++) {
  142.         int f, t;
  143.         cin >> f >> t;
  144.         f--, t--;
  145.         g[f].push_back(t);
  146.         g[t].push_back(f);
  147.     }
  148.     BuildHld(n);
  149.     int q;
  150.     cin >> q;
  151.     while (q--) {
  152.         char ch;
  153.         int a, b;
  154.         cin >> ch >> a >> b;
  155.         if (ch == 'I') {
  156.             a--;
  157.             Upd(a, b);
  158.         } else {
  159.             a--, b--;
  160.             cout << Get(a, b) << "\n";
  161.         }
  162.     }
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement