Ukh1

Hacker earth Fenwick

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