Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- template <class T, class Res = typename T::res_t> struct LazySeg {
- LazySeg() = default;
- LazySeg(uint n) : n(n), sz(getSz(n)), tree(2 * sz) {}
- template <class It> LazySeg(It first, It last) : n(last - first), sz(getSz(n)), tree(2 * sz) {
- auto build = [&](It first, It last, uint u, auto const &f) {
- if (first + 1 == last) return void(tree[u] = *first);
- auto mid = first + (last - first + 1) / 2;
- f(first, mid, 2 * u, f);
- f(mid, last, 2 * u + 1, f);
- tree[u] = tree[2 * u] + tree[2 * u + 1];
- };
- build(first, last, 1, build);
- }
- template <class... Ts> void ModifyExc(uint l, uint r, Ts &&... ts) {
- auto modify = [&](uint u, uint start, uint end, auto const &f) {
- if (r <= start or l >= end) return;
- if (l <= start and r >= end) {
- tree[u].Tag(forward<Ts>(ts)...);
- tree[u].ApplyTag(start, end);
- if (start + 1 == end) tree[u].ClearTag();
- } else {
- push(u, start, end);
- uint mid = (start + end + 1) / 2;
- f(2 * u, start, mid, f);
- f(2 * u + 1, mid, end, f);
- tree[u] = tree[2 * u] + tree[2 * u + 1];
- // fix(u, start, end);
- }
- };
- modify(1, 0, n, modify);
- }
- template <class... Ts> void ModifyInc(uint l, uint r, Ts &&... ts) {
- return ModifyExc(l, r + 1, forward<Ts>(ts)...);
- }
- Res QueryExc(uint l, uint r) {
- auto query = [&](uint u, uint start, uint end, auto const &f) -> Res {
- if (r <= start or l >= end) return {};
- // push(u, start, end);
- if (l <= start and r >= end) return tree[u];
- push(u, start, end);
- uint mid = (start + end + 1) / 2;
- return f(2 * u, start, mid, f) + f(2 * u + 1, mid, end, f);
- };
- return query(1, 0, n, query);
- }
- Res QueryInc(uint l, uint r) { return QueryExc(l, r + 1); }
- private:
- static uint getSz(uint n) {
- if (n == 0) return 1;
- return 1u << (sizeof(uint) * 8 - __builtin_clz(n - 1));
- }
- uint n = 0;
- uint sz = 0;
- vector<T> tree;
- void push(uint u, uint l, uint r) {
- uint mid = (l + r + 1)/2;
- tree[2 * u].AddLazy(tree[u]);
- tree[2 * u].ApplyTag(l, mid);
- tree[2 * u + 1].AddLazy(tree[u]);
- tree[2 * u + 1].ApplyTag(mid, r);
- tree[u].ClearTag();
- }
- // void push(uint u, int l, int r) {
- // tree[u].ApplyTag(l, r);
- // if (l + 1 < r) {
- // tree[2 * u].AddLazy(tree[u]);
- // tree[2 * u + 1].AddLazy(tree[u]);
- // }
- // tree[u].ClearTag();
- // }
- // void fix(uint u, int l, int r) {
- // push(2 * u, l, r), push(2 * u + 1, l, r);
- // tree[u] = tree[2 * u] + tree[2 * u + 1];
- // }
- };
- struct Node {
- using res_t = long;
- static constexpr struct inc_tag_t {
- } inc_tag{};
- static constexpr struct set_tag_t {
- } set_tag{};
- res_t val = 0;
- int inc_lazy = 0;
- int set_lazy = 0;
- Node() = default;
- Node(res_t val_) : val(val_) {}
- operator auto const &() const { return val; }
- void Tag(inc_tag_t, int x) { inc_lazy += x; }
- void Tag(set_tag_t, int x) {
- set_lazy = x;
- inc_lazy = 0;
- }
- void ClearTag() { set_lazy = inc_lazy = 0; }
- void ApplyTag(int l, int r) { // [l, r)
- if (set_lazy) val = 1l * (r - l) * set_lazy;
- if (inc_lazy) val += 1l * (r - l) * inc_lazy;
- }
- void AddLazy(Node &parent) {
- if (parent.set_lazy) {
- inc_lazy = 0;
- set_lazy = parent.set_lazy;
- }
- inc_lazy += parent.inc_lazy;
- }
- };
- void Run() {
- int n, q;
- cin >> n >> q;
- vector<int> A(n);
- for (int &a : A) cin >> a;
- LazySeg<Node> seg(A.begin(), A.end());
- for (int qi = 0; qi < q; ++qi) {
- int t, l, r;
- cin >> t >> l >> r;
- if (t == 1) {
- int x;
- cin >> x;
- seg.ModifyExc(l - 1, r, Node::inc_tag, x);
- } else if (t == 2) {
- int x;
- cin >> x;
- seg.ModifyExc(l - 1, r, Node::set_tag, x);
- } else {
- cout << seg.QueryExc(l - 1, r) << '\n';
- }
- // vector<long> tmp;
- // FOR(i, 0, n) tmp.push_back(seg.QueryInc(i, i));
- // Debug(tmp);
- }
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout << fixed << setprecision(10);
- #ifdef NARUT_LOCAL
- cerr << fixed << setprecision(10);
- assert(freopen("./io/test.in", "r", stdin));
- assert(freopen("./io/test.out", "w", stdout));
- #endif
- Run();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement