Advertisement
ke_timofeeva7

heavy-light decomposition

Aug 3rd, 2022 (edited)
579
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.17 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4. #include <vector>
  5. #include <cmath>
  6. #include <algorithm>
  7. #include <memory.h>
  8. #include <stdio.h>
  9. #include <stack>
  10. #include <deque>
  11. #include <queue>
  12. #include <set>
  13. #include <iterator>
  14. #include <map>
  15. #include <iomanip>
  16. #include <unordered_set>
  17. #include <unordered_map>
  18. #include <array>
  19. #include <random>
  20. #include <ctime>
  21. #include <chrono>
  22. #include <cstdlib>
  23. #define let int
  24. #define int long long
  25. #define pb push_back
  26. #define fir first
  27. #define sec second
  28. #define double long double
  29. #define endl '\n'
  30. #define un unsigned
  31. #define INF 1000000000000009
  32. #define EPS 0.0000000001
  33. #define pii pair<int, int>
  34. #define all(v) v.begin(), v.end()
  35. using namespace std;
  36.  
  37. const int N = 1000009, R = 1 << 20, MOD = 1e9 + 7, ABC = 26;
  38.  
  39. mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  40.  
  41. class SegmentTree {
  42. public:
  43.     vector<int> tree;
  44.     void init(int n) {
  45.         tree.resize(4 * n + 1, 0);
  46.     }
  47.  
  48.     int findMax(int ql, int qr, int v, int nl, int nr) {
  49.         if (ql > nr || qr < nl)
  50.             return 0;
  51.         if (ql <= nl && qr >= nr)
  52.             return tree[v];
  53.         int nm = (nl + nr) / 2;
  54.         return max(findMax(ql, qr, 2 * v, nl, nm), findMax(ql, qr, v * 2 + 1, nm + 1, nr));
  55.     }
  56.  
  57.     void upd(int v, int nl, int nr, int pos, int add) {
  58.         if (nl == nr) {
  59.             tree[v] += add;
  60.             return;
  61.         }
  62.  
  63.         if (v * 2 >= tree.size())
  64.             return;
  65.        
  66.         int nm = (nl + nr) / 2;
  67.         if (pos <= nm)
  68.             upd(2 * v, nl, nm, pos, add);
  69.         else
  70.             upd(2 * v + 1, nm + 1, nr, pos, add);
  71.         tree[v] = max(tree[v * 2 + 1], tree[v * 2]);
  72.     }
  73. };
  74.  
  75. class HeavyLightDecomposition {
  76. private:
  77.     vector<vector<int>> gr_;
  78.     vector<int> sz_;
  79.     SegmentTree tree;
  80.     vector<int> pathNumber_;
  81.     vector<int> timeIn_, timeOut_;
  82.     vector<int> parent_;
  83.  
  84.     int current = 0;
  85.     void dfsBuildPaths(int v, int pr, int path) {
  86.         timeIn_[v] = current++;
  87.         pathNumber_[v] = path;
  88.         for (int i = 0; i < gr_[v].size(); i++) {
  89.             int nv = gr_[v][i];
  90.             if (nv != pr) {
  91.                 if (sz_[nv] * 2 >= sz_[v]) {
  92.                     //swap(gr_[v][i], gr_[v][0]);
  93.                     dfsBuildPaths(nv, v, path);
  94.                 }
  95.                 else {
  96.                     dfsBuildPaths(nv, v, nv);
  97.                 }
  98.             }
  99.         }
  100.         timeOut_[v] = current;
  101.     }  
  102.  
  103.     void dfs(int v, int pr) {
  104.         for (int i = 0; i < gr_[v].size(); i++) {
  105.             int nv = gr_[v][i];
  106.             if (nv != pr) {
  107.                 if (sz_[nv] * 2 >= sz_[v]) {
  108.                     swap(gr_[v][i], gr_[v][0]);
  109.                     dfs(nv, v);
  110.                 }
  111.                 else {
  112.                     dfs(nv, v);
  113.                 }
  114.             }
  115.         }
  116.     }
  117.     void dfsFindSz(int v, int parent) {
  118.         sz_[v] = 1;
  119.         parent_[v] = parent;
  120.         for (int u : gr_[v]) {
  121.             if (parent != u) {
  122.                 dfsFindSz(u, v);
  123.                 sz_[v] += sz_[u];
  124.             }
  125.         }        
  126.     }
  127.  
  128.     bool isAncestor(int u, int v) {
  129.         return timeIn_[u] <= timeIn_[v] && timeOut_[v] <= timeOut_[u];
  130.     }
  131.  
  132. public:
  133.     HeavyLightDecomposition(const vector<vector<int>>& gr) : gr_(gr) {}
  134.  
  135.     void init() {
  136.         int n = gr_.size();
  137.         sz_.assign(n, 0);
  138.         tree.init(n);
  139.         timeIn_.assign(n, 0);
  140.         timeOut_.assign(n, 0);
  141.         parent_.assign(n, -1);
  142.         pathNumber_.assign(n, -1);
  143.         dfsFindSz(0, -1);
  144.         dfs(0, -1);
  145.         dfsBuildPaths(0, -1, 0);
  146.     }
  147.  
  148.     int findMax(int u, int v) {
  149.         int ans = -INF;
  150.  
  151.         while (!isAncestor(pathNumber_[u], v)) {
  152.             int path = pathNumber_[u];
  153.             ans = max(ans, tree.findMax(timeIn_[path], timeIn_[u], 1, 0, tree.tree.size() / 4 - 1));
  154.             u = parent_[path];
  155.         }
  156.  
  157.         while (!isAncestor(pathNumber_[v], u)) {
  158.             int path = pathNumber_[v];
  159.             ans = max(ans, tree.findMax(timeIn_[path], timeIn_[v], 1, 0, tree.tree.size() / 4 - 1));
  160.             v = parent_[path];
  161.         }
  162.  
  163.         if (timeIn_[u] > timeIn_[v])
  164.             swap(u, v);
  165.  
  166.         ans = max(ans, tree.findMax(timeIn_[u], timeIn_[v], 1, 0, tree.tree.size() / 4 - 1));
  167.         return ans;
  168.     }
  169.  
  170.     void update(int pos, int x) {
  171.         tree.upd(1, 0, tree.tree.size() / 4 - 1 , timeIn_[pos], x);
  172.     }
  173. };
  174.  
  175. signed main()
  176. {
  177.     ios_base::sync_with_stdio(false);
  178.     cin.tie(0);
  179.     cout.tie(0);
  180.     srand(time(0));
  181.  
  182.     int n;
  183.     cin >> n;
  184.  
  185.     vector<vector<int>> gr(n);
  186.     for (int i = 0; i < n - 1; i++) {
  187.         int a, b;
  188.         cin >> a >> b;
  189.         a--;
  190.         b--;
  191.         gr[a].push_back(b);
  192.         gr[b].push_back(a);
  193.     }
  194.  
  195.     int q;
  196.     cin >> q;
  197.  
  198.     HeavyLightDecomposition hld(gr);
  199.     hld.init();
  200.  
  201.     while (q--) {
  202.         char c;
  203.         int u, v;
  204.         cin >> c >> u >> v;
  205.  
  206.         if (c == 'I') {
  207.             hld.update(u - 1, v);
  208.         }
  209.         else {
  210.             int ans = hld.findMax(u - 1, v - 1);
  211.             cout << ans << endl;
  212.         }
  213.     }
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement