Advertisement
prog3r

gt(subtree,vertex,path), inc(su btree, vertex) — non HLD

Jun 21st, 2025
466
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.45 KB | None | 0 0
  1. #include <bits/extc++.h>
  2. using namespace std;
  3. using namespace __gnu_pbds;
  4. template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
  5. #define int long long
  6. #define YES(x) cout << (x?"YES\n":"NO\n")
  7. #define NO(x) cout << (x?"NO\n":"YES\n")
  8. #ifdef LO
  9. #pragma GCC optimize("trapv")
  10. #endif
  11. #ifndef LO
  12. #pragma GCC optimize("Ofast,unroll-loops")
  13. #endif
  14. //constexpr int MOD = (119<<23)+1;
  15. //constexpr int MOD = 967276608647009887ll;
  16. //constexpr int MOD = 1e9+7;
  17. constexpr int INF = 1e18;
  18. signed main() {
  19. #ifndef LO
  20.     clog << "FIO\n";
  21.     ios::sync_with_stdio(0);
  22.     cin.tie(0);
  23. #endif
  24. //    int T=1;
  25. //    cin >> T;
  26. //    for (int tt = 0; tt < T; tt += 1) {
  27. //    }
  28.     int n, q;
  29.     cin >> n >> q;
  30.     vector<vector<int>> adj(n);
  31.     vector<int> a(n);
  32.     for (auto &x : a) {
  33.         cin >> x;
  34.     }
  35.     for (int i = 0; i < n-1; i += 1) {
  36.         int u, v;
  37.         cin >> u >> v;
  38.         u -= 1, v -= 1;
  39.         adj[u].push_back(v);
  40.         adj[v].push_back(u);
  41.     }
  42.     vector<int> tin1(n), tout1(n), tin2(n), tout2(n);
  43.     int t1 = 0;
  44.     vector<vector<int>> up(20, vector<int>(n));
  45.     vector<int> d(n);
  46.     auto dfs1 = [&] (auto f, int u, int p) -> void {
  47.         tin1[u] = t1++;
  48.         for (const auto &x : adj[u]) {
  49.             if (x != p) {
  50.                 d[x] = d[u]+1;
  51.                 up[0][x] = u;
  52.                 f(f, x, u);
  53.             }
  54.         }
  55.         tout1[u] = t1-1;
  56.     };
  57.     int t2 = 0;
  58.     auto dfs2 = [&] (auto f, int u, int p) -> void {
  59.         tin2[u] = t2;
  60.         for (const auto &x : adj[u]) {
  61.             if (x != p) {
  62.                 f(f, x, u);
  63.             }
  64.         }
  65.         tout2[u] = t2++;
  66.     };
  67.     dfs1(dfs1, 0, -1);
  68.     dfs2(dfs2, 0, -1);
  69.     for (int i = 1; i < 20; i += 1) {
  70.         for (int j = 0; j < n; j += 1) {
  71.             up[i][j] = up[i-1][up[i-1][j]];
  72.         }
  73.     }
  74.     struct Node {
  75.         int val=0;
  76.         int lz=0;
  77.     };
  78.     auto push = [&] (int u, int tl, int tr, vector<Node>& ST) -> void {
  79.         int tm = (tl + tr) >> 1;
  80.         int szl = tm-tl+1;
  81.         int szr = tr-(tm+1)+1;
  82.         ST[2*u+1].lz += ST[u].lz;
  83.         ST[2*u+1].val += ST[u].lz*szl;
  84.         ST[2*u+2].lz += ST[u].lz;
  85.         ST[2*u+2].val += ST[u].lz*szr;
  86.         ST[u].lz = 0;
  87.     };
  88.     auto inc = [&] (auto f, int u, int tl, int tr, int l, int r, int x, vector<Node>& ST) -> void {
  89.         if (tl == l && tr == r) {
  90.             ST[u].val += x*(tr-tl+1);
  91.             ST[u].lz += x;
  92.             return;
  93.         }
  94.         int tm = (tl + tr) >> 1;
  95.         push(u, tl, tr, ST);
  96.         if (l <= tm) {
  97.             f(f, 2*u+1, tl, tm, l, min(r, tm), x, ST);
  98.         }
  99.         if (r >= tm+1) {
  100.             f(f, 2*u+2, tm+1, tr, max(tm+1, l), r, x, ST);
  101.         }
  102.         ST[u].val = ST[2*u+1].val + ST[2*u+2].val;
  103.     };
  104.     auto gt = [&] (auto f, int u, int tl, int tr, int l, int r, vector<Node>& ST) -> int {
  105.         if (tl == l && tr == r) {
  106.             return ST[u].val;
  107.         }
  108.         int tm = (tl + tr) >> 1;
  109.         push(u, tl, tr, ST);
  110.         int ret = 0;
  111.         if (l <= tm) {
  112.             ret += f(f, 2*u+1, tl, tm, l, min(r, tm), ST);
  113.         }
  114.         if (r >= tm+1) {
  115.             ret += f(f, 2*u+2, tm+1, tr, max(tm+1, l), r, ST);
  116.         }
  117.         return ret;
  118.     };
  119.     vector<Node> _1(4*n+10), _2(4*n+10);
  120.     auto gt_on_path_to_root = [&] (int u) -> int {
  121.         int ret = gt(gt, 0, 0, n-1, 0, tout1[u], _1);
  122.         if (tout2[u]-1 >= 0) {
  123.             ret -= gt(gt, 0, 0, n-1, 0, tout2[u]-1, _2);
  124.         }
  125.         return ret;
  126.     };
  127.     auto inc_vertex = [&] (int u, int x) -> void {
  128.         inc(inc, 0, 0, n-1, tin1[u], tin1[u], x, _1);
  129.         inc(inc, 0, 0, n-1, tout2[u], tout2[u], x, _2);
  130.     };
  131.     auto gt_vertex = [&] (int u) -> int {
  132.         return gt(gt, 0, 0, n-1, tout2[u], tout2[u], _2);
  133.     };
  134.     auto inc_subtree = [&] (int u, int x) -> void {
  135.         inc(inc, 0, 0, n-1, tin1[u], tout1[u], x, _1);
  136.         inc(inc, 0, 0, n-1, tin2[u], tout2[u], x, _2);
  137.     };
  138.     auto gt_subtree = [&] (int u) -> int {
  139.         return gt(gt, 0, 0, n-1, tin1[u], tout1[u], _1);
  140.     };
  141.     auto LCA = [&] (int u, int v) -> int {
  142.         if (d[u] < d[v]) {
  143.             swap(u, v);
  144.         }
  145.         int diff = d[u] - d[v];
  146.         for (int i = 0; i < 20; i += 1) {
  147.             if (diff&(1<<i)) {
  148.                 u = up[i][u];
  149.             }
  150.         }
  151.         if (u == v) {
  152.             return u;
  153.         }
  154.         for (int i = 19; i >= 0; i -= 1) {
  155.             if (up[i][u] != up[i][v]) {
  156.                 u = up[i][u];
  157.                 v = up[i][v];
  158.             }
  159.         }
  160.         return up[0][u];
  161.     };
  162.     auto gt_path = [&] (int u, int v) -> int {
  163.         int lca = LCA(u, v);
  164.         int ret = 0;
  165.         ret += gt_on_path_to_root(u);
  166.         ret += gt_on_path_to_root(v);
  167.         ret -= gt_vertex(lca);
  168.         if (up[0][lca] != lca) {
  169.             ret -= 2ll*gt_on_path_to_root(up[0][lca]);
  170.         }
  171.         return ret;
  172.     };
  173.     for (int i = 0; i < n; i += 1) {
  174.         inc_vertex(i, a[i]);
  175.     }
  176.     for (int ii = 0; ii < q; ii += 1) {
  177.         int tp;
  178.         cin >> tp;
  179.         if (tp == 1) {
  180.             int u, x;
  181.             cin >> u >> x;
  182.             u -= 1;
  183.             inc_vertex(u, x-gt_vertex(u));
  184.         }
  185.         if (tp == 2) {
  186.             int u, v;
  187.             cin >> u >> v;
  188.             u -= 1, v -= 1;
  189.             cout << gt_path(u, v) << "\n";
  190.         }
  191.     }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement