Ukh1

Cses range update range sums hard

Sep 23rd, 2025
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.26 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.  
  26. int lazy_set[MAXN];
  27. VALUE lazy_increase[MAXN];
  28. int n_fenwick;
  29.  
  30. // ===================== Macros for Combine =====================
  31. #define combine_value(a, b) ((a) + (b))
  32. #define DEFAULT_COMBINE (0ll)
  33.  
  34. const int INCREASE = 1;
  35. const int SET = 2;
  36.  
  37. // ===================== Core Functions =====================
  38. bool update_point(int nd, VALUE value, int type) {
  39.     if (type == SET) {
  40.         int64_t delta = value - point[nd];
  41.         point[nd] = value;
  42.         tree[nd] += delta;
  43.         return false;
  44.     } else {
  45.         tree[nd] += value;
  46.         point[nd] += value;
  47.         return false;
  48.     }
  49. }
  50.  
  51. void update_interval(int nd, VALUE value, int type) {
  52.     if (type == SET) {
  53.         lazy_set[nd] = value;
  54.         lazy_increase[nd] = 0;
  55.     } else {
  56.         lazy_increase[nd] += value;
  57.     }
  58.  
  59.     if (type == SET) {
  60.         tree[nd] = value * LSB(nd);
  61.         point[nd] = value;
  62.     } else {
  63.         tree[nd] += value * LSB(nd);
  64.         point[nd] += value;
  65.     }
  66. }
  67.  
  68. #define foreach_fenwick_children(child, nd) \
  69.     for (int sibling = LEFT_SIBLING(nd), child = (nd) - 1; child > sibling; child -= LSB(child))
  70.  
  71. void push_lazy(int nd) {
  72.     if (nd > n_fenwick) return;
  73.     if (!lazy_set[nd] && !lazy_increase[nd]) return;
  74.  
  75.     foreach_fenwick_children(child, nd) {
  76.         if (lazy_set[nd]) {
  77.             update_interval(child, lazy_set[nd], SET);
  78.         }
  79.         if (lazy_increase[nd]) {
  80.             update_interval(child, lazy_increase[nd], INCREASE);
  81.         }
  82.     }
  83.  
  84.     lazy_set[nd] = lazy_increase[nd] = 0;
  85. }
  86.  
  87. int go_up(int lo, int hi, int* record) {
  88.     int cnt = 0;
  89.     while (lo < hi) {
  90.         record[cnt++] = lo;
  91.         lo = PARENT(lo);
  92.     }
  93.     return cnt;
  94. }
  95.  
  96. void pull_lazy(int lo, int hi) {
  97.     static int parent[LOGN];
  98.     int cnt = go_up(PARENT(lo), hi, parent);
  99.     while (cnt--) {
  100.         push_lazy(parent[cnt]);
  101.     }
  102. }
  103.  
  104. void combine(int nd) {
  105.     if (nd > n_fenwick) return;
  106.     tree[nd] = point[nd];
  107.     foreach_fenwick_children(chld, nd) {
  108.         tree[nd] = combine_value(tree[chld], tree[nd]);
  109.     }
  110. }
  111.  
  112. void recalculate(int lo, int hi) {
  113.     while (lo < hi) {
  114.         combine(lo);
  115.         lo = PARENT(lo);
  116.     }
  117. }
  118.  
  119. #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))
  120.  
  121. // ===================== Update / Query =====================
  122. void range_update_fenwick(int l, int r, int v, int type) {
  123.     int previous_node = 0;
  124.     int first_point = 0;
  125.     bool node_dirty = false;
  126.    
  127.     pull_lazy(r, n_fenwick + 1);
  128.    
  129.     fenwick_range_iter(l, r, i, i_point) {
  130.         if (i_point) {
  131.             node_dirty = update_point(i, v, type);
  132.             if (first_point == 0) first_point = i;
  133.             if (l != i || node_dirty) push_lazy(i);
  134.         } else {
  135.             update_interval(i, v, type);
  136.             node_dirty = false;
  137.         }
  138.        
  139.         previous_node = i;
  140.     }
  141.  
  142.     recalculate(PARENT(r), PARENT(first_point ? first_point : previous_node));
  143.     recalculate(node_dirty ? previous_node : PARENT(previous_node),
  144.                 n_fenwick + 1);
  145. }
  146.  
  147. VALUE range_query_fenwick(int l, int r) {
  148.     assert(l <= r);
  149.     VALUE ans;
  150.     bool empty = true;
  151.  
  152.     pull_lazy(r, n_fenwick + 1);
  153.  
  154.     fenwick_range_iter(l, r, i, i_point) {
  155.         const VALUE& segment = i_point ? point[i] : tree[i];
  156.         ans = empty ? segment : combine_value(segment, ans);
  157.         empty = false;
  158.  
  159.         if (i_point && l != i) {
  160.             push_lazy(i);
  161.         }
  162.     }
  163.     return ans;
  164. }
  165.  
  166. // ===================== Main =====================
  167. int main() {
  168.     ios::sync_with_stdio(false);
  169.     cin.tie(nullptr);
  170.  
  171.     int n, q;
  172.     cin >> n >> q;
  173.     n_fenwick = n;
  174.  
  175.     for (int i = 1; i <= n; ++i) {
  176.         tree[i] = DEFAULT_COMBINE;
  177.         lazy_set[i] = 0;
  178.         lazy_increase[i] = 0;
  179.     }
  180.  
  181.     for (int i = 1; i <= n; ++i) {
  182.         VALUE v;
  183.         cin >> v;
  184.         point[i] = v;
  185.         tree[i] = combine_value(tree[i], point[i]);
  186.         int parent = PARENT(i);
  187.         if (parent <= n) {
  188.             tree[parent] = combine_value(tree[parent], tree[i]);
  189.         }
  190.     }
  191.  
  192.     while (q--) {
  193.         int t, a, b, x;
  194.         cin >> t >> a >> b;
  195.  
  196.         if (t == 3) { // Query
  197.             cout << range_query_fenwick(a, b) << endl;
  198.         } else { // Update
  199.             cin >> x;
  200.             range_update_fenwick(a, b, x, t == 1 ? INCREASE : SET);
  201.         }
  202.     }
  203.  
  204.     return 0;
  205. }
Advertisement
Add Comment
Please, Sign In to add comment