Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.12 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. template <class T, class Res = typename T::res_t> struct LazySeg {
  5.     LazySeg() = default;
  6.     LazySeg(uint n) : n(n), sz(getSz(n)), tree(2 * sz) {}
  7.  
  8.     template <class It> LazySeg(It first, It last) : n(last - first), sz(getSz(n)), tree(2 * sz) {
  9.         auto build = [&](It first, It last, uint u, auto const &f) {
  10.             if (first + 1 == last) return void(tree[u] = *first);
  11.             auto mid = first + (last - first + 1) / 2;
  12.             f(first, mid, 2 * u, f);
  13.             f(mid, last, 2 * u + 1, f);
  14.             tree[u] = tree[2 * u] + tree[2 * u + 1];
  15.         };
  16.         build(first, last, 1, build);
  17.     }
  18.  
  19.     template <class... Ts> void ModifyExc(uint l, uint r, Ts &&... ts) {
  20.         auto modify = [&](uint u, uint start, uint end, auto const &f) {
  21.             if (r <= start or l >= end) return;
  22.             if (l <= start and r >= end) {
  23.                 tree[u].Tag(forward<Ts>(ts)...);
  24.                 tree[u].ApplyTag(start, end);
  25.                 if (start + 1 == end) tree[u].ClearTag();
  26.             } else {
  27.                 push(u, start, end);
  28.                 uint mid = (start + end + 1) / 2;
  29.                 f(2 * u, start, mid, f);
  30.                 f(2 * u + 1, mid, end, f);
  31.                 tree[u] = tree[2 * u] + tree[2 * u + 1];
  32.                 // fix(u, start, end);
  33.             }
  34.         };
  35.         modify(1, 0, n, modify);
  36.     }
  37.     template <class... Ts> void ModifyInc(uint l, uint r, Ts &&... ts) {
  38.         return ModifyExc(l, r + 1, forward<Ts>(ts)...);
  39.     }
  40.  
  41.     Res QueryExc(uint l, uint r) {
  42.         auto query = [&](uint u, uint start, uint end, auto const &f) -> Res {
  43.             if (r <= start or l >= end) return {};
  44.             // push(u, start, end);
  45.             if (l <= start and r >= end) return tree[u];
  46.             push(u, start, end);
  47.             uint mid = (start + end + 1) / 2;
  48.             return f(2 * u, start, mid, f) + f(2 * u + 1, mid, end, f);
  49.         };
  50.         return query(1, 0, n, query);
  51.     }
  52.     Res QueryInc(uint l, uint r) { return QueryExc(l, r + 1); }
  53.  
  54.   private:
  55.     static uint getSz(uint n) {
  56.         if (n == 0) return 1;
  57.         return 1u << (sizeof(uint) * 8 - __builtin_clz(n - 1));
  58.     }
  59.     uint n = 0;
  60.     uint sz = 0;
  61.     vector<T> tree;
  62.  
  63.     void push(uint u, uint l, uint r) {
  64.         uint mid = (l + r + 1)/2;
  65.         tree[2 * u].AddLazy(tree[u]);
  66.         tree[2 * u].ApplyTag(l, mid);
  67.  
  68.         tree[2 * u + 1].AddLazy(tree[u]);
  69.         tree[2 * u + 1].ApplyTag(mid, r);
  70.  
  71.         tree[u].ClearTag();
  72.     }
  73.     // void push(uint u, int l, int r) {
  74.     //  tree[u].ApplyTag(l, r);
  75.     //  if (l + 1 < r) {
  76.     //      tree[2 * u].AddLazy(tree[u]);
  77.     //      tree[2 * u + 1].AddLazy(tree[u]);
  78.     //  }
  79.     //  tree[u].ClearTag();
  80.     // }
  81.     // void fix(uint u, int l, int r) {
  82.     //  push(2 * u, l, r), push(2 * u + 1, l, r);
  83.     //  tree[u] = tree[2 * u] + tree[2 * u + 1];
  84.     // }
  85. };
  86.  
  87. struct Node {
  88.     using res_t = long;
  89.  
  90.     static constexpr struct inc_tag_t {
  91.     } inc_tag{};
  92.     static constexpr struct set_tag_t {
  93.     } set_tag{};
  94.  
  95.     res_t val = 0;
  96.     int inc_lazy = 0;
  97.     int set_lazy = 0;
  98.  
  99.     Node() = default;
  100.     Node(res_t val_) : val(val_) {}
  101.     operator auto const &() const { return val; }
  102.  
  103.     void Tag(inc_tag_t, int x) { inc_lazy += x; }
  104.  
  105.     void Tag(set_tag_t, int x) {
  106.         set_lazy = x;
  107.         inc_lazy = 0;
  108.     }
  109.  
  110.     void ClearTag() { set_lazy = inc_lazy = 0; }
  111.  
  112.     void ApplyTag(int l, int r) { // [l, r)
  113.         if (set_lazy) val = 1l * (r - l) * set_lazy;
  114.         if (inc_lazy) val += 1l * (r - l) * inc_lazy;
  115.     }
  116.  
  117.     void AddLazy(Node &parent) {
  118.         if (parent.set_lazy) {
  119.             inc_lazy = 0;
  120.             set_lazy = parent.set_lazy;
  121.         }
  122.         inc_lazy += parent.inc_lazy;
  123.     }
  124. };
  125.  
  126. void Run() {
  127.     int n, q;
  128.     cin >> n >> q;
  129.     vector<int> A(n);
  130.     for (int &a : A) cin >> a;
  131.  
  132.     LazySeg<Node> seg(A.begin(), A.end());
  133.  
  134.     for (int qi = 0; qi < q; ++qi) {
  135.         int t, l, r;
  136.         cin >> t >> l >> r;
  137.         if (t == 1) {
  138.             int x;
  139.             cin >> x;
  140.             seg.ModifyExc(l - 1, r, Node::inc_tag, x);
  141.         } else if (t == 2) {
  142.             int x;
  143.             cin >> x;
  144.             seg.ModifyExc(l - 1, r, Node::set_tag, x);
  145.         } else {
  146.             cout << seg.QueryExc(l - 1, r) << '\n';
  147.         }
  148.  
  149.         // vector<long> tmp;
  150.         // FOR(i, 0, n) tmp.push_back(seg.QueryInc(i, i));
  151.         // Debug(tmp);
  152.     }
  153. }
  154.  
  155. int main() {
  156.     ios_base::sync_with_stdio(false);
  157.     cin.tie(nullptr);
  158.     cout << fixed << setprecision(10);
  159. #ifdef NARUT_LOCAL
  160.     cerr << fixed << setprecision(10);
  161.     assert(freopen("./io/test.in", "r", stdin));
  162.     assert(freopen("./io/test.out", "w", stdout));
  163. #endif
  164.  
  165.     Run();
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement