Advertisement
prog3r

+= на пути за log_2 n

Jun 24th, 2025
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.07 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.     for (int i = 0; i < n-1; i += 1) {
  32.         int u, v;
  33.         cin >> u >> v;
  34.         u -= 1, v -= 1;
  35.         adj[u].push_back(v);
  36.         adj[v].push_back(u);
  37.     }
  38.     vector<int> tin1(n), tout1(n), tin2(n), tout2(n);
  39.     int t1 = 0;
  40.     vector<vector<int>> up(20, vector<int>(n));
  41.     vector<int> d(n);
  42.     auto dfs1 = [&] (auto f, int u, int p) -> void {
  43.         tin1[u] = t1++;
  44.         for (const auto &x : adj[u]) {
  45.             if (x != p) {
  46.                 d[x] = d[u]+1;
  47.                 up[0][x] = u;
  48.                 f(f, x, u);
  49.             }
  50.         }
  51.         tout1[u] = t1-1;
  52.     };
  53.     int t2 = 0;
  54.     auto dfs2 = [&] (auto f, int u, int p) -> void {
  55.         tin2[u] = t2;
  56.         for (const auto &x : adj[u]) {
  57.             if (x != p) {
  58.                 f(f, x, u);
  59.             }
  60.         }
  61.         tout2[u] = t2++;
  62.     };
  63.     dfs1(dfs1, 0, -1);
  64.     dfs2(dfs2, 0, -1);
  65.     for (int i = 1; i < 20; i += 1) {
  66.         for (int j = 0; j < n; j += 1) {
  67.             up[i][j] = up[i-1][up[i-1][j]];
  68.         }
  69.     }
  70.     struct Node {
  71.         int val=0;
  72.         int lz=0;
  73.     };
  74.     auto push = [&] (int u, int tl, int tr, vector<Node>& ST) -> void {
  75.         int tm = (tl + tr) >> 1;
  76.         int szl = tm-tl+1;
  77.         int szr = tr-(tm+1)+1;
  78.         ST[2*u+1].lz += ST[u].lz;
  79.         ST[2*u+1].val += ST[u].lz*szl;
  80.         ST[2*u+2].lz += ST[u].lz;
  81.         ST[2*u+2].val += ST[u].lz*szr;
  82.         ST[u].lz = 0;
  83.     };
  84.     auto inc = [&] (auto f, int u, int tl, int tr, int l, int r, int x, vector<Node>& ST) -> void {
  85.         if (tl == l && tr == r) {
  86.             ST[u].val += x*(tr-tl+1);
  87.             ST[u].lz += x;
  88.             return;
  89.         }
  90.         int tm = (tl + tr) >> 1;
  91.         push(u, tl, tr, ST);
  92.         if (l <= tm) {
  93.             f(f, 2*u+1, tl, tm, l, min(r, tm), x, ST);
  94.         }
  95.         if (r >= tm+1) {
  96.             f(f, 2*u+2, tm+1, tr, max(tm+1, l), r, x, ST);
  97.         }
  98.         ST[u].val = ST[2*u+1].val + ST[2*u+2].val;
  99.     };
  100.     auto gt = [&] (auto f, int u, int tl, int tr, int l, int r, vector<Node>& ST) -> int {
  101.         if (tl == l && tr == r) {
  102.             return ST[u].val;
  103.         }
  104.         int tm = (tl + tr) >> 1;
  105.         push(u, tl, tr, ST);
  106.         int ret = 0;
  107.         if (l <= tm) {
  108.             ret += f(f, 2*u+1, tl, tm, l, min(r, tm), ST);
  109.         }
  110.         if (r >= tm+1) {
  111.             ret += f(f, 2*u+2, tm+1, tr, max(tm+1, l), r, ST);
  112.         }
  113.         return ret;
  114.     };
  115.     vector<Node> vals(4*n+10), cancelled(4*n+10);
  116.     auto inc_on_path_to_root = [&] (int u, int x) -> void {
  117.         inc(inc, 0, 0, n-1, 0, tout1[u], x, vals);
  118.         if (tout2[u]-1 >= 0) {
  119.             inc(inc, 0, 0, n-1, 0, tout2[u]-1, x, cancelled);
  120.         }
  121.     };
  122.     vector<int> a(n);
  123.     auto inc_vertex = [&] (int u, int x) -> void {
  124.         a[u] += x;
  125.     };
  126.     auto gt_vertex = [&] (int u) -> int {
  127.         return a[u]+gt(gt, 0, 0, n-1, tin1[u], tin1[u], vals)-gt(gt, 0, 0, n-1, tout2[u], tout2[u], cancelled);
  128.     };
  129.     auto LCA = [&] (int u, int v) -> int {
  130.         if (d[u] < d[v]) {
  131.             swap(u, v);
  132.         }
  133.         int diff = d[u] - d[v];
  134.         for (int i = 0; i < 20; i += 1) {
  135.             if (diff&(1<<i)) {
  136.                 u = up[i][u];
  137.             }
  138.         }
  139.         if (u == v) {
  140.             return u;
  141.         }
  142.         for (int i = 19; i >= 0; i -= 1) {
  143.             if (up[i][u] != up[i][v]) {
  144.                 u = up[i][u];
  145.                 v = up[i][v];
  146.             }
  147.         }
  148.         return up[0][u];
  149.     };
  150.     auto inc_path = [&] (int u, int v, int x) -> void {
  151.         int lca = LCA(u, v);
  152.         inc_on_path_to_root(u, x);
  153.         inc_on_path_to_root(v, x);
  154.         inc_vertex(lca, -x);
  155.         if (up[0][lca] != lca) {
  156.             inc_on_path_to_root(up[0][lca], -2ll*x);
  157.         }
  158.     };
  159.     int ans = 0;
  160.     for (int ii = 0; ii < q; ii += 1) {
  161.         int tp;
  162.         cin >> tp;
  163.         if (tp == 1) {
  164.             int u, v, x;
  165.             cin >> u >> v >> x;
  166.             u -= 1, v -= 1;
  167.             inc_path(u, v, x);
  168.         }
  169.         if (tp == 2) {
  170.             int u;
  171.             cin >> u;
  172.             u -= 1;
  173.             ans ^= gt_vertex(u);
  174.         }
  175.         if (ii % 100 == 99) {
  176.             cout << ans << endl;
  177.             ans = 0;
  178.         }
  179.     }
  180. }
  181.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement