Guest User

Cses range update

a guest
Sep 23rd, 2025
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.75 KB | None | 0 0
  1. #include <iostream>     // For cin, cout
  2. #include<cassert>
  3. #include <vector>       // For vector container
  4. #include <tuple>        // For tuple
  5. #include <random>       // For mt19937 and uniform_int_distribution
  6. #include <chrono>       // For timing
  7. #include <algorithm>    // For swap
  8. #include <cstdint>      // For int64_t if needed
  9.  
  10. using namespace std;
  11. using namespace chrono;
  12.  
  13. // ===================== Configuration =====================
  14. #define VALUE uint64_t
  15. #define MAXN 200001
  16. #define LSB(x)           ((x) & -(x))
  17. #define PARENT(x)        ((x) + LSB(x))
  18. #define LEFT_SIBLING(x)  ((x) - LSB(x))
  19.  
  20. const int LOGN = 18;
  21.  
  22. // ===================== Global Arrays =====================
  23. VALUE point[MAXN];
  24. VALUE tree[MAXN];
  25. VALUE lazy[MAXN];
  26. bool has_lazy[MAXN];
  27. int n_fenwick;
  28.  
  29. // ===================== Macros for Combine =====================
  30.  
  31. #define combine_value(a, b) ((a) + (b))
  32. #define DEFAULT_COMBINE     (0)
  33.  
  34. // ===================== Core Functions =====================
  35. bool update_point(int nd, int v) {
  36.     point[nd] += v;
  37.     tree[nd] += v;
  38.     // smart move to update parent
  39.     // the node is not dirty so we return false
  40.     return false;
  41. }
  42.  
  43. void update_interval(int nd, VALUE value) {
  44.     has_lazy[nd] = 1;
  45.     lazy[nd] += value;
  46.     tree[nd] += value * 1ll * LSB(nd);
  47.     point[nd] += value;
  48. }
  49.  
  50. #define foreach_fenwick_children(child, nd) \
  51.     for (int sibling = LEFT_SIBLING(nd), child = (nd) - 1; child > sibling; child -= LSB(child))
  52.  
  53. void push_lazy(int nd) {
  54.     if (nd > n_fenwick) return;
  55.     if (!has_lazy[nd]) return;
  56.  
  57.     foreach_fenwick_children(child, nd) {
  58.         update_interval(child, lazy[nd]);
  59.     }
  60.     has_lazy[nd] = false;
  61.     lazy[nd] = 0;
  62. }
  63.  
  64. int go_up(int lo, int hi, int* record) {
  65.     int cnt = 0;
  66.     while (lo < hi) {
  67.         record[cnt++] = lo;
  68.         lo = PARENT(lo);
  69.     }
  70.     return cnt;
  71. }
  72.  
  73. void pull_lazy(int lo, int hi) {
  74.     static int parent[LOGN];
  75.     int cnt = go_up(PARENT(lo), hi, parent);
  76.     while (cnt--) {
  77.         push_lazy(parent[cnt]);
  78.     }
  79. }
  80.  
  81. void combine(int nd) {
  82.     if (nd > n_fenwick) return;
  83.     tree[nd] = point[nd];
  84.     foreach_fenwick_children(chld, nd) {
  85.         tree[nd] = combine_value(tree[chld], tree[nd]);
  86.     }
  87. }
  88.  
  89. void recalculate(int lo, int hi) {
  90.     while (lo < hi) {
  91.         combine(lo);
  92.         lo = PARENT(lo);
  93.     }
  94. }
  95.  
  96. #define fenwick_range_iter(l, r, i, i_point) for (int i = (r), next_r, i_point;(l) <= i && (next_r = LEFT_SIBLING(i), (i_point = (next_r < (l) - 1)), true);i = (i_point ? i - 1 : next_r))
  97.  
  98. // ===================== Update / Query =====================
  99. void range_update_fenwick(int l, int r, int v) {
  100.     int previous_node = 0;
  101.     int first_point = 0;
  102.     bool node_dirty = false;
  103.    
  104.     pull_lazy(r, n_fenwick + 1);
  105.    
  106.     fenwick_range_iter(l, r, i, i_point) {
  107.         if (i_point) {
  108.             node_dirty = update_point(i, v);
  109.             if (first_point == 0) first_point = i;
  110.             if (l != i || node_dirty) push_lazy(i);
  111.         } else {
  112.             update_interval(i, v);
  113.             node_dirty = false;
  114.         }
  115.        
  116.         previous_node = i;
  117.     }
  118.  
  119.     recalculate(PARENT(r), PARENT(first_point ? first_point : previous_node));
  120.     recalculate(node_dirty ? previous_node : PARENT(previous_node),
  121.                 n_fenwick + 1);
  122. }
  123.  
  124. VALUE range_query_fenwick(int l, int r) {
  125.     assert(l <= r);
  126.     VALUE ans;
  127.     bool empty = true;
  128.  
  129.     pull_lazy(r, n_fenwick + 1);
  130.  
  131.     fenwick_range_iter(l, r, i, i_point) {
  132.         const VALUE& segment = i_point ? point[i] : tree[i];
  133.         ans = empty ? segment : combine_value(segment, ans);
  134.         empty = false;
  135.  
  136.         if (i_point && l != i) {
  137.             push_lazy(i);
  138.         }
  139.     }
  140.     return ans;
  141. }
  142.  
  143. int main() {
  144.     ios::sync_with_stdio(false);
  145.     cin.tie(nullptr);
  146.  
  147.     int t = 1;
  148.  
  149.     while (t--) {
  150.         int n, q;
  151.         cin >> n >> q;
  152.  
  153.         n_fenwick = n;
  154.         for (int i = 1; i <= n; ++i) {
  155.             tree[i] = DEFAULT_COMBINE;
  156.             lazy[i] = 0;
  157.             has_lazy[i] = false;
  158.         }
  159.  
  160.         for (int i = 1; i <= n; ++i) {
  161.             cin >> point[i];
  162.             tree[i] = combine_value(tree[i], point[i]);
  163.  
  164.             int parent = PARENT(i);
  165.             if (parent <= n) {
  166.                 tree[parent] = combine_value(tree[parent], tree[i]);
  167.             }
  168.         }
  169.  
  170.         while (q--) {
  171.             int type;
  172.             cin >> type;
  173.             if (type == 1) {
  174.                 int a, b, u;
  175.                 cin >> a >> b >> u;
  176.                 range_update_fenwick(a, b, u);
  177.             } else {
  178.                 int a;
  179.                 cin >> a;
  180.                 cout << range_query_fenwick(a, a) << "\n";
  181.             }
  182.         }
  183.     }
  184.     return 0;
  185. }
Advertisement
Add Comment
Please, Sign In to add comment