Problem:
Resource of the Planet Yanaizu
Humanity has finally discovered the planet Yanaizu, which is home to intelligent life. As science progressed on Yanaiizu, collaboration with us gradually became more and more active.
On the planet Yanaizu, an insect called Beko is considered to be an important resource. It grows from a larva to an adult. In their habitat, there are several colonies of Beko larvae living in swarms, and these colonies are arranged in a row. Using the biotechnology of the planet Yanaizu, the following operations can be performed on the swarms.
Add the same number of larvae to all swarms in a given range.
Hatch the specified number of larvae into adults in all the swarms in the specified range, and find the total number of hatched larvae. At this point, we can specify only one number of larvae to be hatched.
In the second operation, if the number of larvae in a group is less than the specified number, all the larvae in that group are hatched. For example, if there are three larvae in group 1 and two larvae in group 2, and the number of larvae to be hatched in groups 1 to 2 is 3, then three larvae from group 1 and two larvae from group 2 will be hatched into adults. In this case, the total number of larvae hatched is five.
In this collaborative research, we humans were in charge of simulating these operations on Beko larvae. This is the time to show the power of our science.
Given the information about the larvae in each swarms, write a program to simulate the operations on them.
Input
The input is given in the following form.
$N$
$c_1$
$c_2$
:
$c_N$
$M$
$manip_1$
$manip_2$
:
$manip_M$
In the first line, the number of swarms $N$ ($1 \leq N \leq 100,000$) is given. In the following $N$ lines, the number of larvae in each swarm $c_i$ ($0 \leq c_i \leq 100,000$) is given.
In the next line, the number of operations $M$ ($1 \leq M \leq 100,000$) is given. In the following $M$ lines, the contents of the operations are given. The content of each operation is one of the following:
1 $a$ $b$ $d$
or
2 $a$ $b$ $d$
If the first number is 1, add $d$ larvae ($1 \leq d \leq 1,000$) to the swarm in the specified range $a$ to $b$ ($1 \leq a \leq b \leq N$). When the first number is 2, it represents the operation to hatch $d$ larvae ($1 \leq d \leq 1,000$) into adults in all the swarms in the range $a$ to $b$ ($1 \leq a \leq b \leq N$). In this case, the total number of larvae actually hatched should be output. It is assumed that at least one operation with a leading number of 2 is always given.
Output
Output the total number of larvae actually hatched in a line for each operation that hatches larvae.
Sample Input and Output
Sample Input
3
1
2
3
3
2 1 3 2
1 1 2 5
2 2 3 3
Sample Output
5
4

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,popcnt")

// --------- Fast IO ----------
namespace fastio {
    static const int SZ = 1 << 20;
    char ibuf[SZ]; int ipos = 0, ilen = 0;
    inline char getch() {
        if (ipos >= ilen) {
            ilen = (int)fread(ibuf, 1, SZ, stdin);
            ipos = 0;
            if (ilen == 0) return 0;
        }
        return ibuf[ipos++];
    }
    inline bool readInt(int &out) {
        char c; int sgn = 1; int x = 0;
        do { c = getch(); if (!c) return false; } while (c <= ' ');
        if (c == '-') { sgn = -1; c = getch(); }
        for (; '0' <= c && c <= '9'; c = getch()) x = x*10 + (c - '0');
        out = x * sgn; return true;
    }
    static const int OSZ = 1 << 20;
    char obuf[OSZ]; int opos = 0;
    inline void putch(char c) {
        if (opos >= OSZ) { fwrite(obuf, 1, OSZ, stdout); opos = 0; }
        obuf[opos++] = c;
    }
    inline void writeLL(long long x) {
        if (x == 0) { putch('0'); return; }
        if (x < 0) { putch('-'); x = -x; }
        char s[24]; int n = 0;
        while (x) { s[n++] = char('0' + (x % 10)); x /= 10; }
        while (n--) putch(s[n]);
    }
    inline void writeNL() { putch('\n'); }
    inline void flush() { fwrite(obuf, 1, opos, stdout); opos = 0; }
}
using fastio::readInt;

// --------- Segment Tree Beats (min side + add) ----------
struct SegTree {
    int n;
    static constexpr int INF = 0x3f3f3f3f;

    vector<long long> sum;
    vector<int> min1, min2, cntMin, add;

    SegTree(int n): n(n),
        sum(4*n, 0), min1(4*n, 0), min2(4*n, INF),
        cntMin(4*n, 0), add(4*n, 0) {}

    inline void apply_add(int p, int len, int v) {
        sum[p] += 1LL * v * len;
        min1[p] += v;
        if (min2[p] < INF) min2[p] += v;
        add[p] += v;
    }

    inline void pushMin(int p, int v) { // raise min1 to v (v > min1 && v <= min2)
        if (v <= min1[p]) return;
        sum[p] += 1LL * (v - min1[p]) * cntMin[p];
        min1[p] = v;
        // min2 unchanged; invariant maintained
    }

    inline void pull(int p) {
        int lc = p<<1, rc = lc|1;
        sum[p] = sum[lc] + sum[rc];

        if (min1[lc] < min1[rc]) {
            min1[p] = min1[lc];
            cntMin[p] = cntMin[lc];
            min2[p] = std::min(min2[lc], min1[rc]);
        } else if (min1[rc] < min1[lc]) {
            min1[p] = min1[rc];
            cntMin[p] = cntMin[rc];
            min2[p] = std::min(min1[lc], min2[rc]);
        } else {
            min1[p] = min1[lc];
            cntMin[p] = cntMin[lc] + cntMin[rc];
            min2[p] = std::min(min2[lc], min2[rc]);
        }
    }

    inline void push(int p, int l, int r) {
        if (l == r) { add[p] = 0; return; }
        int lc = p<<1, rc = lc|1;
        int m = (l + r) >> 1;
        if (add[p]) {
            int v = add[p];
            apply_add(lc, m - l + 1, v);
            apply_add(rc, r - m, v);
            add[p] = 0;
        }
        // ensure children min >= parent min
        if (min1[lc] < min1[p]) pushMin(lc, min1[p]);
        if (min1[rc] < min1[p]) pushMin(rc, min1[p]);
    }

    void build(int p, int l, int r, const vector<int>& a) {
        if (l == r) {
            int v = a[l];
            sum[p] = v;
            min1[p] = v;
            min2[p] = INF;
            cntMin[p] = 1;
            add[p] = 0;
            return;
        }
        int m = (l + r) >> 1;
        build(p<<1, l, m, a);
        build(p<<1|1, m+1, r, a);
        pull(p);
    }

    void range_add(int p, int l, int r, int ql, int qr, int v) {
        if (qr < l || r < ql) return;
        if (ql <= l && r <= qr) {
            apply_add(p, r - l + 1, v);
            return;
        }
        push(p, l, r);
        int m = (l + r) >> 1;
        range_add(p<<1, l, m, ql, qr, v);
        range_add(p<<1|1, m+1, r, ql, qr, v);
        pull(p);
    }

    // range chmax with x = 0
    void range_chmax0(int p, int l, int r, int ql, int qr) {
        if (qr < l || r < ql || min1[p] >= 0) return;
        if (ql <= l && r <= qr && min2[p] > 0) {
            pushMin(p, 0);
            return;
        }
        push(p, l, r);
        int m = (l + r) >> 1;
        range_chmax0(p<<1, l, m, ql, qr);
        range_chmax0(p<<1|1, m+1, r, ql, qr);
        pull(p);
    }

    long long range_sum(int p, int l, int r, int ql, int qr) {
        if (qr < l || r < ql) return 0;
        if (ql <= l && r <= qr) return sum[p];
        push(p, l, r);
        int m = (l + r) >> 1;
        return range_sum(p<<1, l, m, ql, qr)
             + range_sum(p<<1|1, m+1, r, ql, qr);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    if (!readInt(N)) return 0;
    vector<int> a(N+1);
    for (int i = 1; i <= N; ++i) readInt(a[i]);

    SegTree seg(N);
    seg.build(1, 1, N, a);

    int M; readInt(M);
    for (int i = 0; i < M; ++i) {
        int t, l, r, d;
        readInt(t); readInt(l); readInt(r); readInt(d);
        if (t == 1) {
            seg.range_add(1, 1, N, l, r, d);
        } else { // t == 2
            long long S0 = seg.range_sum(1, 1, N, l, r);
            seg.range_add(1, 1, N, l, r, -d);
            seg.range_chmax0(1, 1, N, l, r);
            long long S1 = seg.range_sum(1, 1, N, l, r);
            fastio::writeLL(S0 - S1);
            fastio::writeNL();
        }
    }
    fastio::flush();
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 14628
final_rank: 1

code_snippet: // AOJ #0427 Resource of the Planet Yanaizu
// 2025.4.19

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 0x3f3f3f3f;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct Node {
    ll sum;
    int mn, smn;
    int cm;
    ll add;
};

vector<Node> st;
vector<int> c;
int n, m;

void pull(int o) {
    const auto &L = st[o<<1], &R = st[o<<1|1];
    st[o].sum = L.sum + R.sum;
    if (L.mn < R.mn) {
        st[o].mn = L.mn;
        st[o].cm = L.cm;
        st[o].smn = min(L.smn, R.mn);
    } else if (L.mn > R.mn) {
        st[o].mn = R.mn;
        st[o].cm = R.cm;
        st[o].smn = min(L.mn, R.smn);
    } else {
        st[o].mn = L.mn;
        st[o].cm = L.cm + R.cm;
        st[o].smn = min(L.smn, R.smn);
    }
}

void apply_add(int o, ll v, int len) {
    st[o].sum += v * len;
    st[o].mn  = int(st[o].mn + v);
    st[o].smn = (st[o].smn < INF ? int(st[o].smn + v) : INF);
    st[o].add += v;
}

void apply_chmax(int o, int x) {
    if (st[o].mn >= x) return;
    st[o].sum += ll(x - st[o].mn) * st[o].cm;
    st[o].mn = x;
    if (st[o].smn < x) st[o].smn = x;
}

void push(int o, int l, int r) {
    int m = (l + r) >> 1;
    int lc = o<<1, rc = o<<1|1;
    if (st[o].add) {
        apply_add(lc, st[o].add, m - l + 1);
        apply_add(rc, st[o].add, r - m);
        st[o].add = 0;
    }
    apply_chmax(lc, st[o].mn);
    apply_chmax(rc, st[o].mn);
}

void build(int o, int l, int r) {
    st[o].add = 0;
    if (l == r) {
        st[o].sum = st[o].mn = c[l];
        st[o].smn = INF;
        st[o].cm  = 1;
        return;
    }
    int m = (l + r) >> 1;
    build(o<<1, l, m);
    build(o<<1|1, m+1, r);
    pull(o);
}

void range_add(int o, int l, int r, int ql, int qr, ll v) {
    if (ql <= l && r <= qr) {
        apply_add(o, v, r - l + 1);
        return;
    }
    push(o, l, r);
    int m = (l + r) >> 1;
    if (ql <= m) range_add(o<<1, l, m, ql, qr, v);
    if (qr >  m) range_add(o<<1|1, m+1, r, ql, qr, v);
    pull(o);
}

void range_chmax(int o, int l, int r, int ql, int qr, int x) {
    if (st[o].mn >= x || qr < l || r < ql) return;
    if (ql <= l && r <= qr && st[o].smn > x) {
        apply_chmax(o, x);
        return;
    }
    push(o, l, r);
    int m = (l + r) >> 1;
    if (ql <= m) range_chmax(o<<1, l, m, ql, qr, x);
    if (qr >  m) range_chmax(o<<1|1, m+1, r, ql, qr, x);
    pull(o);
}

ll range_sum(int o, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return st[o].sum;
    push(o, l, r);
    int m = (l + r) >> 1;
    ll ans = 0;
    if (ql <= m) ans += range_sum(o<<1, l, m, ql, qr);
    if (qr >  m) ans += range_sum(o<<1|1, m+1, r, ql, qr);
    return ans;
}

int main(){
    n = Cin();
    c.resize(n+1);
    for (int i = 1; i <= n; i++) c[i] = Cin();

    st.resize(4*(n+1));
    build(1, 1, n);

    m = Cin();
    while (m--) {
        int t = Cin(), a = Cin(), b = Cin(), d = Cin();
        if (t == 1) {
            range_add(1, 1, n, a, b, d);
        } else {
            ll before = range_sum(1, 1, n, a, b);
            range_add    (1, 1, n, a, b, -d);
            range_chmax(1, 1, n, a, b, 0);
            ll after  = range_sum(1, 1, n, a, b);
            Cout(before - after);
        }
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 15884
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
const int INF = 1e9+100;
const ll INFL = 3e18+100;
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define chmin(a, b) a=min(a, b)
#define chmax(a, b) a=max(a, b)
#define rep(i,n) for(int i=0;i<(n);++i)
ll POW(ll x, ll n, ll m=INFL){ll res=1;x%=m;while(n){if(n&1)res=res*x%m;x=x*x%m;n>>=1ll;}return res;}

struct Segtree_beats {
    ll op(int type, ll x, ll y) { return type ? min(x, y) : max(x, y); }
    bool cmp(int type, ll x, ll y) { return type ? x < y : x > y; }
    struct alignas(32) Node {
        ll sum = 0;
        ll a1[2] = {}, a2[2] = {-INFL, INFL}, ac[2] = {1, 1}, add = 0;
    };
    vector<Node> v;
    ll n, log, e[3] = {-INFL, INFL, 0};
    Segtree_beats() {}
    Segtree_beats(int n) : Segtree_beats(vector<ll>(n)) {}
    Segtree_beats(const vector<ll>& a) {
        n = 1, log = 0;
        while (n < (int)a.size()) n <<= 1, log++;
        v.resize(2 * n);
        rep(i, (int)a.size()) {
            v[i + n].sum = v[i + n].a1[0] = v[i + n].a1[1] = a[i];
        }
        for (int i = n - 1; i >= 1; --i) update(i);
    }
    
    // 0 : add, 1 : chmin, 2 : chmax, 3 : update
    template <int cmd> void apply(int l, int r, ll x) {
        if (l == r) return;
        l += n, r += n;
        for (int i = log; i >= 1; --i) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) _apply<cmd>(l++, x);
                if (r & 1) _apply<cmd>(--r, x);
                l >>= 1;
                r >>= 1;
            }
            l = l2, r = r2;
        }
        for (int i = 1; i <= log; ++i) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }
    
    // 0 : max, 1 : min, 2 : sum
    template <int cmd> ll fold(int l, int r) {
        if (l == r) return 0;
        l += n, r += n;
        for (int i = log; i >= 1; --i) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        ll lx = e[cmd], rx = e[cmd];
        while (l < r) {
            if (l & 1) op<cmd>(lx, v[l++]);
            if (r & 1) op<cmd>(rx, v[--r]);
            l >>= 1;
            r >>= 1;
        }
        if constexpr (cmd <= 1) lx = op(cmd, lx, rx);
        if constexpr (cmd == 2) lx += rx;
        return lx;
    }
private:
    void update(int k) {
        Node& p = v[k];
        Node& l = v[k * 2 + 0];
        Node& r = v[k * 2 + 1];
        p.sum = l.sum + r.sum;
        rep(t, 2) {
            if (l.a1[t] == r.a1[t]) {
                p.a1[t] = l.a1[t];
                p.a2[t] = op(t, l.a2[t], r.a2[t]);
                p.ac[t] = l.ac[t] + r.ac[t];
            } else {
                bool f = cmp(t, l.a1[t], r.a1[t]);
                p.a1[t] = f ? l.a1[t] : r.a1[t];
                p.ac[t] = f ? l.ac[t] : r.ac[t];
                p.a2[t] = op(t, f ? r.a1[t] : l.a1[t],
                                 f ? l.a2[t] : r.a2[t]);
            }
        }
    }
    void push_add(int k, ll x) {
        Node& p = v[k];
        p.sum += x << (log + __builtin_clz(k) - 31);
        rep(t, 2) {
            p.a1[t] += x;
            if (p.a2[t] != e[t]) p.a2[t] += x;
        }
        p.add += x;
    }
    void push(int cmd, int k, ll x) {
        Node& p = v[k];
        p.sum += (x - p.a1[cmd]) * p.ac[cmd];
        if (p.a1[cmd ^ 1] == p.a1[cmd]) p.a1[cmd ^ 1] = x;
        if (p.a2[cmd ^ 1] == p.a1[cmd]) p.a2[cmd ^ 1] = x;
        p.a1[cmd] = x;
    }
    void push(int k) {
        Node& p = v[k];
        if (p.add) {
            rep(t, 2) push_add(k * 2 + t, p.add);
            p.add = 0;
        }
        rep(t, 2) rep(s, 2) if (cmp(t, v[k * 2 + s].a1[t], p.a1[t]))
            push(t, k * 2 + s, p.a1[t]);
    }
    void subtree_ch(int cmd, int k, ll x) {
        if (!cmp(cmd, v[k].a1[cmd], x)) return;
        if (cmp(cmd, x, v[k].a2[cmd])) {
            return push(cmd, k, x);
        }
        push(k);
        rep(t, 2) subtree_ch(cmd, k * 2 + t, x);
        update(k);
    }
    template <int cmd> inline void _apply(int k, ll x) {
        rep(i, 2) if (cmd >> i & 1) subtree_ch(i, k, x);
        if constexpr (cmd == 0) push_add(k, x);
    }
    template <int cmd> inline void op(ll& a, const Node& b) {
        if constexpr (cmd <= 1) a = op(cmd, a, b.a1[cmd]);
        if constexpr (cmd == 2) a += b.sum;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    vector<ll> c(n);
    rep(i,n) cin >> c[i];

    Segtree_beats seg(c);


    int m;
    cin >> m;
    rep(i,m){
        int t,a,b,d;
        cin >> t >> a >> b >> d;
        a--;
        if(t==1){
            seg.apply<0>(a,b,d);
        }
        else{
            ll mae = seg.fold<2>(a,b);
            seg.apply<0>(a,b,-d);
            seg.apply<2>(a,b,0);
            ll ato = seg.fold<2>(a,b);
            
            cout << mae-ato << endl;
        }
    }
}
accuracy: 1
time_ms: 260
memory_kb: 20308
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);++i)
using namespace std;
using ll = long long;

#include <bits/stdc++.h>
using namespace std;

template<class T>
struct SegmentTree {
    const T INF = numeric_limits<T>::max() / 2;
    int n;
    vector<T> max_v, smax_v, max_c;
    vector<T> min_v, smin_v, min_c;
    vector<T> sum;
    vector<T> len;
    vector<T> lazy;
    vector<bool> fail;

    SegmentTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        max_v.resize(2*n, -INF);
        smax_v.resize(2*n, -INF);
        max_c.resize(2*n);
        min_v.resize(2*n, INF);
        smin_v.resize(2*n, INF);
        min_c.resize(2*n);
        sum.resize(2*n);
        len.resize(2*n);
        lazy.resize(2*n);
        fail.resize(2*n);
        for(int i=0; i<n; i++) len[i+n] = 1;
        for(int i=n-1; i>0; i--) len[i] = len[2*i] + len[2*i+1];
    }

    void update_node_max(int k, T x) {
        sum[k] += (x - max_v[k]) * max_c[k];
        if(max_v[k] == min_v[k]) {
            max_v[k] = min_v[k] = x;
        } else if(max_v[k] == smin_v[k]) {
            max_v[k] = smin_v[k] = x;
        } else {
            max_v[k] = x;
        }
    }

    void update_node_min(int k, T x) {
        sum[k] += (x - min_v[k]) * min_c[k];
        if(max_v[k] == min_v[k]) {
            max_v[k] = min_v[k] = x;
        } else if(smax_v[k] == min_v[k]) {
            min_v[k] = smax_v[k] = x;
        } else {
            min_v[k] = x;
        }
    }

    void push_add(int k, T x) {
        max_v[k] += x;
        if(smax_v[k] != -INF) smax_v[k] += x;
        min_v[k] += x;
        if(smin_v[k] != INF) smin_v[k] += x;
        sum[k] += x * len[k];
        lazy[k] += x;
    }

    void push(int k) {
        if(lazy[k] != 0) {
            push_add(2*k, lazy[k]);
            push_add(2*k+1, lazy[k]);
            lazy[k] = 0;
        }
        if(max_v[k] < max_v[2*k]) {
            update_node_max(2*k, max_v[k]);
        }
        if(min_v[k] > min_v[2*k]) {
            update_node_min(2*k, min_v[k]);
        }
        if(max_v[k] < max_v[2*k+1]) {
            update_node_max(2*k+1, max_v[k]);
        }
        if(min_v[k] > min_v[2*k+1]) {
            update_node_min(2*k+1, min_v[k]);
        }
    }

    void update(int k) {
        sum[k] = sum[2*k] + sum[2*k+1];

        if(max_v[2*k] > max_v[2*k+1]) {
            max_v[k] = max_v[2*k];
            max_c[k] = max_c[2*k];
            smax_v[k] = max(smax_v[2*k], max_v[2*k+1]);
        } else if(max_v[2*k] < max_v[2*k+1]) {
            max_v[k] = max_v[2*k+1];
            max_c[k] = max_c[2*k+1];
            smax_v[k] = max(max_v[2*k], smax_v[2*k+1]);
        } else {
            max_v[k] = max_v[2*k];
            max_c[k] = max_c[2*k] + max_c[2*k+1];
            smax_v[k] = max(smax_v[2*k], smax_v[2*k+1]);
        }

        if(min_v[2*k] < min_v[2*k+1]) {
            min_v[k] = min_v[2*k];
            min_c[k] = min_c[2*k];
            smin_v[k] = min(smin_v[2*k], min_v[2*k+1]);
        } else if(min_v[2*k] > min_v[2*k+1]) {
            min_v[k] = min_v[2*k+1];
            min_c[k] = min_c[2*k+1];
            smin_v[k] = min(min_v[2*k], smin_v[2*k+1]);
        } else {
            min_v[k] = min_v[2*k];
            min_c[k] = min_c[2*k] + min_c[2*k+1];
            smin_v[k] = min(smin_v[2*k], smin_v[2*k+1]);
        }
    }

    void _update_add(int a, int b, T x, int k, int l, int r) {
        if(b <= l || r <= a) return;
        if(a <= l && r <= b) {
            push_add(k, x);
            return;
        }
        push(k);
        int m = (l + r) >> 1;
        _update_add(a, b, x, 2*k, l, m);
        _update_add(a, b, x, 2*k+1, m, r);
        update(k);
    }

    void _update_chmax(int a, int b, T x, int k, int l, int r) {
        if(b <= l || r <= a || max_v[k] <= x) return;
        if(a <= l && r <= b && smax_v[k] < x) {
            update_node_max(k, x);
            return;
        }
        push(k);
        int m = (l + r) >> 1;
        _update_chmax(a, b, x, 2*k, l, m);
        _update_chmax(a, b, x, 2*k+1, m, r);
        update(k);
    }

    void _update_chmin(int a, int b, T x, int k, int l, int r) {
        if(b <= l || r <= a || min_v[k] >= x) return;
        if(a <= l && r <= b && smin_v[k] > x) {
            update_node_min(k, x);
            return;
        }
        push(k);
        int m = (l + r) >> 1;
        _update_chmin(a, b, x, 2*k, l, m);
        _update_chmin(a, b, x, 2*k+1, m, r);
        update(k);
    }

    T _query_sum(int a, int b, int k, int l, int r) {
        if(b <= l || r <= a) return 0;
        if(a <= l && r <= b) return sum[k];
        push(k);
        int m = (l + r) >> 1;
        return _query_sum(a, b, 2*k, l, m) + _query_sum(a, b, 2*k+1, m, r);
    }

    // 初期化
    void build(const vector<T>& v) {
        int n_ = v.size();
        for(int i=0; i<n_; i++) {
            max_v[n+i] = min_v[n+i] = sum[n+i] = v[i];
            smax_v[n+i] = -INF;
            smin_v[n+i] = INF;
            max_c[n+i] = min_c[n+i] = 1;
        }
        for(int i=n_; i<n; i++) {
            max_v[n+i] = -INF;
            smax_v[n+i] = -INF;
            min_v[n+i] = INF;
            smin_v[n+i] = INF;
            max_c[n+i] = min_c[n+i] = 0;
        }
        for(int i=n-1; i>0; i--) update(i);
    }

    // 区間[a,b)に値xを加算
    void update_add(int a, int b, T x) {
        _update_add(a, b, x, 1, 0, n);
    }

    // 区間[a,b)をx以上にする
    void update_chmax(int a, int b, T x) {
        _update_chmax(a, b, x, 1, 0, n);
    }

    // 区間[a,b)をx以下にする
    void update_chmin(int a, int b, T x) {
        _update_chmin(a, b, x, 1, 0, n);
    }

    // 区間[a,b)の総和を求める
    T query_sum(int a, int b) {
        return _query_sum(a, b, 1, 0, n);
    }
};


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    vector<ll> c(n);
    rep(i,n) cin >> c[i];

    SegmentTree<ll> seg(n);
    seg.build(c);


    int m;
    cin >> m;
    rep(i,m){
        int t,a,b,d;
        cin >> t >> a >> b >> d;
        a--;
        if(t==1){
            seg.update_add(a,b,d);
        }
        else{
            ll mae = seg.query_sum(a,b);
            seg.update_add(a,b,-d);
            seg.update_chmin(a,b,0);
            ll ato = seg.query_sum(a,b);
            
            cout << mae-ato << endl;
        }
    }
    
}
accuracy: 1
time_ms: 300
memory_kb: 22364
final_rank: 13

code_snippet: #include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<iomanip>
#include<queue>
#include<set>
#include<functional>
#include<tuple>
#include<bitset>
#include<cassert>
#include<cstdint>
#include<complex>
#include<random>
#include<fstream>
#include <unordered_map>  
using namespace std;
bool printb(bool f) {
	if (f)printf("Yes\n");
	else printf("No\n");
	return f;
}
template<class T>
void prt(T t = "", string sep = "\n") { cout << t << sep; return; }
template<class T>
void printl(vector<T> a, string sep = " ") {
	for (int i = 0; i < a.size(); i++) {
		cout << a[i];
		if (i != a.size() - 1)cout << sep;
	}
	cout << "\n";
	return;
}
bool prt_isfixed = false;
template<class T>
void prt_fix(T t, string sep = "\n") {
	if (!prt_isfixed) {
		cout << fixed << setprecision(15);
		prt_isfixed = true;
	}
	prt(t, sep);
}
#define all(a) a.begin(),a.end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using uint = unsigned int;
using llong = long long;
using ullong = unsigned long long;
using pii = pair<int, int>;
using pll = pair<llong, llong>;
using pli = pair<llong, int>;
using pil = pair<int, llong>;
template<typename T> using vec2 = vector<vector<T>>;
template<typename T> inline bool chmin(T& a, T b) { return (a > b) ? (a = b, true) : false; }
template<typename T> inline bool chmax(T& a, T b) { return (a < b) ? (a = b, true) : false; }
bool bitIn(llong a, int b) { return ((a >> b) & 1); }
int bitCnt(llong a) {
	int re = 0;
	while (a > 0) {
		if (a & 1)re++;
		a >>= 1;
	}
	return re;
}
llong powL(llong n, llong i) {
	llong re = 1;
	while (i >= 1) {
		if (i & 1) re *= n;
		n *= n;
		i >>= 1;
	}
	return re;
}
llong powL_M(llong n, llong i, llong mod) {
	llong re = 1;
	while (i >= 1) {
		if (i & 1) {
			re *= n;
			re %= mod;
		}
		n *= n;
		n %= mod;
		i >>= 1;
	}
	return re;
}
int  dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
int dx8[8] = { 0,1,1,1,0,-1,-1,-1 }, dy8[8] = { -1,-1,0,1,1,1,0,-1 };

struct segtree_beats {
	int n;
	vector<llong> max_v, smax_v, sum, max_c, lazy, sz;

	void update_node_max(int i, llong x) {
		//v[i]の範囲の最大値をxに更新し、合計も更新
		//smax_v[i]<x<max[i]
		sum[i] -= (max_v[i] - x) * max_c[i];
		max_v[i] = x;
	}
	void addall(int i, llong x) {
		//v[i]の表す範囲全体にxを足す
		max_v[i] += x;
		if (smax_v[i] != -1e10)smax_v[i] += x;
		sum[i] += x * sz[i];
		lazy[i] += x;
	}

	void pushdown(int k) {
		if (lazy[k] != 0) {
			addall(2 * k, lazy[k]);
			addall(2 * k + 1, lazy[k]);
			lazy[k] = 0;
		}
		if (max_v[k] < max_v[2 * k]) {
			update_node_max(2 * k, max_v[k]);
		}
		if (max_v[k] < max_v[2 * k + 1]) {
			update_node_max(2 * k + 1, max_v[k]);
		}
	}
	void pushup(int k) {
		sum[k] = sum[2 * k + 1] + sum[2 * k];

		if (max_v[2 * k] > max_v[2 * k + 1]) {
			max_v[k] = max_v[2 * k];
			max_c[k] = max_c[2 * k];
			smax_v[k] = max(max_v[2 * k + 1], smax_v[2 * k]);
		}
		else if (max_v[2 * k] < max_v[2 * k + 1]) {
			max_v[k] = max_v[2 * k + 1];
			max_c[k] = max_c[2 * k + 1];
			smax_v[k] = max(max_v[2 * k], smax_v[2 * k + 1]);
		}
		else {
			max_v[k] = max_v[2 * k];
			max_c[k] = max_c[2 * k] + max_c[2 * k + 1];
			smax_v[k] = max(smax_v[2 * k], smax_v[2 * k + 1]);
		}
	}
	void update_chmin(int a, int b, llong x, int k = 1, int l = 0, int r = -1) {
		if (r == -1)r = n;
		if (b <= l || r <= a || max_v[k] <= x)return;
		if (a <= l && r <= b && smax_v[k] < x) {
			update_node_max(k, x);
			return;
		}

		pushdown(k);
		update_chmin(a, b, x, 2 * k, l, (l + r) / 2);
		update_chmin(a, b, x, 2 * k + 1, (l + r) / 2, r);
		pushup(k);
		return;
	}
	void update_add(int a, int b, llong x, int k = 1, int l = 0, int r = -1) {
		if (r == -1)r = n;

		if (b <= l || r <= a)return;
		if (a <= l && r <= b) {
			addall(k, x);
			return;
		}
		pushdown(k);
		update_add(a, b, x, 2 * k, l, (l + r) / 2);
		update_add(a, b, x, 2 * k + 1, (l + r) / 2, r);	
		pushup(k);
		return;
	}
	llong query(int a, int b, int k = 1, int l = 0, int r = -1) {
		if (r == -1)r = n;

		if (b <= l || r <= a)return 0;
		if (a <= l && r <= b) {
			return sum[k];
		}
		pushdown(k);
		return query(a, b, 2 * k, l, (l + r) / 2) + query(a, b, 2 * k + 1, (l + r) / 2, r);
	}


	segtree_beats(vector<llong>& a) {
		n = 1;
		while (n < a.size())n <<= 1;
		max_v.resize(2 * n, 0);
		smax_v.resize(2 * n, -1e18);
		sum.resize(2 * n, 0);
		max_c.resize(2 * n, 1);
		lazy.resize(2 * n, 0);
		sz.resize(2 * n, 1);

		rep(i, a.size()) {
			max_v[i + n] = sum[i + n] = a[i];
		}
		for (int i = n - 1; i > 0; i--) {
			pushup(i);
			sz[i] = sz[i * 2] + sz[i * 2 + 1];
		}
	}
};

int main() {
	int n;
	cin >> n;
	vector<llong> c(n);
	rep(i, n)scanf("%d", &c[i]);
	rep(i, n)c[i] = -c[i];
	segtree_beats seg(c);


	//全てマイナスで管理する
	int m;
	cin >> m;
	while (m--) {
		int f;
		int a, b, d;
		scanf("%d %d %d %d", &f, &a, &b, &d);
		a--;
		if (f == 1) {
			seg.update_add(a, b, -d);
		}
		if (f == 2) {
			int fi = seg.query(a, b);
			seg.update_add(a, b, d);
			seg.update_chmin(a, b, 0);
			int se = seg.query(a, b);
			prt(se - fi);
		}
	}


}
accuracy: 1
time_ms: 170
memory_kb: 16412
final_rank: 3

code_snippet: #include<bits/stdc++.h>
#define overload(a,b,c,d,...) d
#define rep1(a) for(ll _=0;_<(ll)a;++_)
#define rep2(i,n) for(ll i=0;i<(ll)n;++i)
#define rep3(i,l,r) for(ll i=(ll)l;i<(ll)r;++i)
#define rep(...) overload(__VA_ARGS__,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,a) for(ll i=(ll)a-1;i>=0;--i)
#define rrep2(i,a,b) for(ll i=(ll)b-1;i>=(ll)a;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pb push_back
#define eb emplace_back
using namespace std;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
template<typename T,typename U>inline bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>inline bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
static constexpr ll mod1=998244353;
static constexpr ll mod=1000000007;
static constexpr ll inf=numeric_limits<ll>::max()/2;
template<class T>
struct SegmentTreeBeats{
  private:
  static constexpr T INF=numeric_limits<T>::max();
  struct S{
    T sum=0,b1=0,s1=0,b2=-INF,s2=INF,b_cnt=1,s_cnt=1,add=0;
    S(){}
    S(const T&a):sum(a),b1(a),s1(a){}
  };
  vector<S>seq;
  int size=1,idx=0;
  void update(int k){
    S&s=seq[k];
    S&l=seq[2*k];
    S&r=seq[2*k+1];
    s.sum=l.sum+r.sum;
    if(l.b1==r.b1){
      s.b1=l.b1;
      s.b2=max(l.b2,r.b2);
      s.b_cnt=l.b_cnt+r.b_cnt;
    }
    else{
      s.b1=max(l.b1,r.b1);
      s.b2=max(l.b1>r.b1?l.b2:l.b1,l.b1>r.b1?r.b1:r.b2);
      s.b_cnt=l.b1>r.b1?l.b_cnt:r.b_cnt;
    }
    if(l.s1==r.s1){
      s.s1=l.s1;
      s.s2=min(l.s2,r.s2);
      s.s_cnt=l.s_cnt+r.s_cnt;
    }
    else{
      s.s1=min(l.s1,r.s1);
      s.s2=min(l.s1>r.s1?l.s1:l.s2,l.s1>r.s1?r.s2:r.s1);
      s.s_cnt=l.s1>r.s1?r.s_cnt:l.s_cnt;
    }
  }
  void eval_add(int k,T x){
    S&s=seq[k];
    s.sum+=x<<(idx+__builtin_clz(k)-31);
    s.b1+=x,s.s1+=x;
    if(s.b2!=-INF)s.b2+=x;
    if(s.s2!=INF)s.s2+=x;
    s.add+=x;
  }
  void eval_min(int k,T x){
    S&s=seq[k];
    s.sum+=(x-s.b1)*s.b_cnt;
    if(s.s1==s.b1)s.s1=x;
    if(s.s2==s.b1)s.s2=x;
    s.b1=x;
  }
  void eval_max(int k,T x){
    S&s=seq[k];
    s.sum+=(x-s.s1)*s.s_cnt;
    if(s.b1==s.s1)s.b1=x;
    if(s.b2==s.s1)s.b2=x;
    s.s1=x;
  }
  void eval(int k){
    S&s=seq[k];
    if(s.add!=0){
      eval_add(k*2,s.add);
      eval_add(k*2+1,s.add);
      s.add=0;
    }
    if(s.b1<seq[2*k].b1)eval_min(2*k,s.b1);
    if(s.s1>seq[2*k].s1)eval_max(2*k,s.s1);
    if(s.b1<seq[2*k+1].b1)eval_min(2*k+1,s.b1);
    if(s.s1>seq[2*k+1].s1)eval_max(2*k+1,s.s1);
  }
  void apply_min(int k,T x){
    if(seq[k].b1<=x)return;
    if(seq[k].b2<x){
      eval_min(k,x);
      return;
    }
    eval(k);
    apply_min(2*k,x);
    apply_min(2*k+1,x);
    update(k);
  }
  void apply_max(int k,T x){
    if(seq[k].s1>=x)return;
    if(seq[k].s2>x){
      eval_max(k,x);
      return;
    }
    eval(k);
    apply_max(2*k,x);
    apply_max(2*k+1,x);
    update(k);
  }
  void inner_chmin(int l,int r,T x){
    if(l==r)return;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    int l2=l,r2=r;
    while(l<r){
      if(l&1)apply_min(l++,x);
      if(r&1)apply_min(--r,x);
      l>>=1;
      r>>=1;
    }
    l=l2,r=r2;
    for(int i=1;i<=idx;i++){
      if(((l>>i)<<i)!=l)update(l>>i);
      if(((r>>i)<<i)!=r)update(r>>i);
    }
  }
  void inner_chmax(int l,int r,T x){
    if(l==r)return;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    int l2=l,r2=r;
    while(l<r){
      if(l&1)apply_max(l++,x);
      if(r&1)apply_max(--r,x);
      l>>=1;
      r>>=1;
    }
    l=l2,r=r2;
    for(int i=1;i<=idx;i++){
      if(((l>>i)<<i)!=l)update(l>>i);
      if(((r>>i)<<i)!=r)update(r>>i);
    }
  }
  void inner_add(int l,int r,T x){
    if(l==r)return;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    int l2=l,r2=r;
    while(l<r){
      if(l&1)eval_add(l++,x);
      if(r&1)eval_add(--r,x);
      l>>=1;
      r>>=1;
    }
    l=l2,r=r2;
    for(int i=1;i<=idx;i++){
      if(((l>>i)<<i)!=l)update(l>>i);
      if(((r>>i)<<i)!=r)update(r>>i);
    }
  }
  void inner_update(int l,int r,T x){
    if(l==r)return;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    int l2=l,r2=r;
    while(l<r){
      if(l&1)apply_min(l++,x),apply_max(l,x);
      if(r&1)apply_min(--r,x),apply_max(r,x);
      l>>=1;
      r>>=1;
    }
    l=l2,r=r2;
    for(int i=1;i<=idx;i++){
      if(((l>>i)<<i)!=l)update(l>>i);
      if(((r>>i)<<i)!=r)update(r>>i);
    }
  }
  T inner_min(int l,int r){
    if(l==r)return INF;
    T sml=INF,smr=INF;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    while(l<r){
      if(l&1)sml=min(sml,seq[l++].s1);
      if(r&1)smr=min(seq[--r].s1,smr);
      l>>=1,r>>=1;
    }
    return min(sml,smr);
  }
  T inner_max(int l,int r){
    if(l==r)return -INF;
    T sml=-INF,smr=-INF;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    while(l<r){
      if(l&1)sml=max(sml,seq[l++].b1);
      if(r&1)smr=max(seq[--r].b1,smr);
      l>>=1,r>>=1;
    }
    return max(sml,smr);
  }
  T inner_sum(int l,int r){
    if(l==r)return 0;
    T sml=0,smr=0;
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    while(l<r){
      if(l&1)sml+=seq[l++].sum;
      if(r&1)smr+=seq[--r].sum;
      l>>=1,r>>=1;
    }
    return sml+smr;
  }
  public:
  SegmentTreeBeats(){}
  SegmentTreeBeats(int n):SegmentTreeBeats(vector<T>(n)){}
  SegmentTreeBeats(const vector<T>&v){
    const int n=v.size();
    while(size<n)size<<=1,idx++;
    seq.resize(2*size);
    for(int i=0;i<n;i++)seq[i+size]=v[i];
    for(int i=size-1;i;i--)update(i);
  }
  void range_chmin(int l,int r,T x){inner_chmin(l,r,x);}
  void range_chmax(int l,int r,T x){inner_chmax(l,r,x);}
  void range_add(int l,int r,T x){inner_add(l,r,x);}
  void range_update(int l,int r,T x){inner_update(l,r,x);}
  T range_min(int l,int r){return inner_min(l,r);}
  T range_max(int l,int r){return inner_max(l,r);}
  T range_sum(int l,int r){return inner_sum(l,r);}
};
int main(){
	int n;cin>>n;
	vector<ll>c(n);
	for(auto&e:c)cin>>e;
	ll m;cin>>m;
	SegmentTreeBeats<ll>seg(c);
	//rep(i,n)cerr<<seg.range_sum(i,i+1)<<" ";
	//cerr<<endl;
	while(m--){
		ll t,a,b,d;cin>>t>>a>>b>>d;
		a--;
		if(t==1){
			seg.range_add(a,b,d);
		}
		else if(t==2){
			ll sum=seg.range_sum(a,b);
			seg.range_add(a,b,-d);
			seg.range_chmax(a,b,0);
			sum-=seg.range_sum(a,b);
			cout<<sum<<endl;
		}
	}
	
}
accuracy: 1
time_ms: 240
memory_kb: 20328
final_rank: 11

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<functional>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cassert>
#include<ctime>
using namespace std;

#define mind(a,b) (a>b?b:a)
#define maxd(a,b) (a>b?a:b)
#define absd(x) (x<0?-(x):x)
#define pow2(x) ((x)*(x))
#define rep(i,n) for(int i=0; i<n; ++i)
#define repr(i,n) for(int i=n-1; i>=0; --i)
#define repl(i,s,n) for(int i=s; i<=n; ++i)
#define replr(i,s,n) for(int i=n; i>=s; --i)
#define repf(i,s,n,j) for(int i=s; i<=n; i+=j)
#define repe(e,obj) for(auto e : obj)

#define SP << " " <<
#define COL << " : " <<
#define COM << ", " <<
#define ARR << " -> " <<
#define PNT(STR) cout << STR << endl
#define POS(X,Y) "(" << X << ", " << Y << ")"
#define DEB(A) " (" << #A << ") " << A
#define DEBREP(i,n,val) for(int i=0; i<n; ++i) cout << val << " "; cout << endl
#define ALL(V) (V).begin(), (V).end()
#define INF 1000000007
#define INFLL 1000000000000000007LL
#define EPS 1e-9

typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
#define P_TYPE int
typedef pair<P_TYPE, P_TYPE> P;
typedef pair<P, P_TYPE> PI;
typedef pair<P_TYPE, P> IP;
typedef pair<P, P> PP;
typedef priority_queue<P, vector<P>, greater<P> > pvqueue;

#define N 100000

class SegmentTree {
  const ll inf = 1e18;

  int n0;
  ll min_v[N*4], smin_v[N*4], min_c[N*4], lazy[N*4];
  ll sum[N*4];
  ll sz[N*4];

  void update_min(int k, ll x) {
    sum[k] += (x - min_v[k]) * min_c[k];
    min_v[k] = x;
  }

  void lazy_add(int k, ll x) {
    min_v[k] += x;
    smin_v[k] += x;
    lazy[k] += x;
    sum[k] += x * sz[k];
  }

  void push(int k) {
    if(n0 <= k) return;

    if(lazy[k]) {
      lazy_add(2*k, lazy[k]);
      lazy_add(2*k+1, lazy[k]);
      lazy[k] = 0;
    }

    if(min_v[2*k] < min_v[k]) {
      update_min(2*k, min_v[k]);
    }
    if(min_v[2*k+1] < min_v[k]) {
      update_min(2*k+1, min_v[k]);
    }
  }

  void update(int k) {
    if(n0 <= k) return;

    sum[k] = sum[2*k] + sum[2*k+1];
    if(min_v[2*k] < min_v[2*k+1]) {
      min_v[k] = min_v[2*k];
      smin_v[k] = min(smin_v[2*k], min_v[2*k+1]);
      min_c[k] = min_c[2*k];
    } else if(min_v[2*k] > min_v[2*k+1]) {
      min_v[k] = min_v[2*k+1];
      smin_v[k] = min(min_v[2*k], smin_v[2*k+1]);
      min_c[k] = min_c[2*k+1];
    } else {
      min_v[k] = min_v[2*k];
      smin_v[k] = min(smin_v[2*k], smin_v[2*k+1]);
      min_c[k] = min_c[2*k] + min_c[2*k+1];
    }
  }

  ll _query(ll x, int k) {
    push(k);
    if(x <= min_v[k]) {
      lazy_add(k, -x);
      return x * sz[k];
    }
    if(x < smin_v[k]) {
      lazy_add(k, -x);
      ll res = x * sz[k] + min_v[k] * min_c[k];
      update_min(k, 0);
      return res;
    }

    ll lv = _query(x, 2*k);
    ll rv = _query(x, 2*k+1);
    update(k);
    return lv + rv;
  }

  ll _range_query(ll x, int a, int b, int k, int l, int r) {
    if(a <= l && r <= b) {
      return _query(x, k);
    } else if(r <= a || b <= l) {
      return 0;
    }

    push(k);
    ll lv = _range_query(x, a, b, 2*k, l, (l+r)/2);
    ll rv = _range_query(x, a, b, 2*k+1, (l+r)/2, r);
    update(k);
    return lv + rv;
  }

  void _range_add(ll x, int a, int b, int k, int l, int r) {
    push(k);
    if(a <= l && r <= b) {
      lazy_add(k, x);
      return;
    } else if(r <= a || b <= l) {
      return;
    }
    _range_add(x, a, b, 2*k, l, (l+r)/2);
    _range_add(x, a, b, 2*k+1, (l+r)/2, r);
    update(k);
  }

public:
  SegmentTree(int n, ll *a) {
    n0 = 1;
    while(n0 < n) n0 <<= 1;
    rep(i, 2*n0) lazy[i] = sum[i] = sz[i] = 0, min_v[i] = smin_v[i] = inf;
    rep(i, n) min_v[n0+i] = sum[n0+i] = a[i], min_c[n0+i] = sz[n0+i] = 1;
    repr(i, n0) update(i), sz[i] = sz[2*i] + sz[2*i+1];
  }

  ll range_query(int l, int r, ll x) {
    return _range_query(x, l, r, 1, 0, n0);
  }

  void range_add(int l, int r, ll x) {
    _range_add(x, l, r, 1, 0, n0);
  }
};

int main() {
  int n, m;
  ll a[N];
  cin >> n;
  rep(i, n) cin >> a[i];
  SegmentTree st(n, a);
  cin >> m;
  rep(_, m) {
    int t, a, b, d;
    cin >> t >> a >> b >> d;
    switch(t) {
    case 1:
      st.range_add(a-1, b, d);
      break;
    case 2:
      cout << st.range_query(a-1, b, d) << endl;
      break;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 22812
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// Segment Tree Beats
// - l<=i<r について、 A_i の値を min(A_i, x) に更新
// - l<=i<r について、 A_i の値を max(A_i, x) に更新
// - l<=i<r の中の A_i の最大値を求める
// - l<=i<r の中の A_i の最小値を求める
// - l<=i<r の A_i の和を求める
// - l<=i<r について、 A_i の値に x を加える
// - l<=i<r について、 A_i の値を x に更新

#define N 100000

class SegmentTree {
  const ll inf = 1e18;
  int n, n0;
  ll max_v[4*N], smax_v[4*N], max_c[4*N];
  ll min_v[4*N], smin_v[4*N], min_c[4*N];
  ll sum[4*N];
  ll len[4*N], ladd[4*N], lval[4*N];

  void update_node_max(int k, ll x) {
    sum[k] += (x - max_v[k]) * max_c[k];

    if(max_v[k] == min_v[k]) {
      max_v[k] = min_v[k] = x;
    } else if(max_v[k] == smin_v[k]) {
      max_v[k] = smin_v[k] = x;
    } else {
      max_v[k] = x;
    }

    if(lval[k] != inf && x < lval[k]) {
      lval[k] = x;
    }
  }
  void update_node_min(int k, ll x) {
    sum[k] += (x - min_v[k]) * min_c[k];

    if(max_v[k] == min_v[k]) {
      max_v[k] = min_v[k] = x;
    } else if(smax_v[k] == min_v[k]) {
      min_v[k] = smax_v[k] = x;
    } else {
      min_v[k] = x;
    }

    if(lval[k] != inf && lval[k] < x) {
      lval[k] = x;
    }
  }

  void push(int k) {

    if(n0-1 <= k) return;

    if(lval[k] != inf) {
      updateall(2*k+1, lval[k]);
      updateall(2*k+2, lval[k]);
      lval[k] = inf;
      return;
    }

    if(ladd[k] != 0) {
      addall(2*k+1, ladd[k]);
      addall(2*k+2, ladd[k]);
      ladd[k] = 0;
    }

    if(max_v[k] < max_v[2*k+1]) {
      update_node_max(2*k+1, max_v[k]);
    }
    if(min_v[2*k+1] < min_v[k]) {
      update_node_min(2*k+1, min_v[k]);
    }

    if(max_v[k] < max_v[2*k+2]) {
      update_node_max(2*k+2, max_v[k]);
    }
    if(min_v[2*k+2] < min_v[k]) {
      update_node_min(2*k+2, min_v[k]);
    }
  }

  void update(int k) {
    sum[k] = sum[2*k+1] + sum[2*k+2];

    if(max_v[2*k+1] < max_v[2*k+2]) {
      max_v[k] = max_v[2*k+2];
      max_c[k] = max_c[2*k+2];
      smax_v[k] = max(max_v[2*k+1], smax_v[2*k+2]);
    } else if(max_v[2*k+1] > max_v[2*k+2]) {
      max_v[k] = max_v[2*k+1];
      max_c[k] = max_c[2*k+1];
      smax_v[k] = max(smax_v[2*k+1], max_v[2*k+2]);
    } else {
      max_v[k] = max_v[2*k+1];
      max_c[k] = max_c[2*k+1] + max_c[2*k+2];
      smax_v[k] = max(smax_v[2*k+1], smax_v[2*k+2]);
    }

    if(min_v[2*k+1] < min_v[2*k+2]) {
      min_v[k] = min_v[2*k+1];
      min_c[k] = min_c[2*k+1];
      smin_v[k] = min(smin_v[2*k+1], min_v[2*k+2]);
    } else if(min_v[2*k+1] > min_v[2*k+2]) {
      min_v[k] = min_v[2*k+2];
      min_c[k] = min_c[2*k+2];
      smin_v[k] = min(min_v[2*k+1], smin_v[2*k+2]);
    } else {
      min_v[k] = min_v[2*k+1];
      min_c[k] = min_c[2*k+1] + min_c[2*k+2];
      smin_v[k] = min(smin_v[2*k+1], smin_v[2*k+2]);
    }
  }

  void _update_min(ll x, int a, int b, int k, int l, int r) {
    if(b <= l || r <= a || max_v[k] <= x) {
      return;
    }
    if(a <= l && r <= b && smax_v[k] < x) {
      update_node_max(k, x);
      return;
    }

    push(k);
    _update_min(x, a, b, 2*k+1, l, (l+r)/2);
    _update_min(x, a, b, 2*k+2, (l+r)/2, r);
    update(k);
  }

  void _update_max(ll x, int a, int b, int k, int l, int r) {
    if(b <= l || r <= a || x <= min_v[k]) {
      return;
    }
    if(a <= l && r <= b && x < smin_v[k]) {
      update_node_min(k, x);
      return;
    }

    push(k);
    _update_max(x, a, b, 2*k+1, l, (l+r)/2);
    _update_max(x, a, b, 2*k+2, (l+r)/2, r);
    update(k);
  }

  void addall(int k, ll x) {
    max_v[k] += x;
    if(smax_v[k] != -inf) smax_v[k] += x;
    min_v[k] += x;
    if(smin_v[k] != inf) smin_v[k] += x;

    sum[k] += len[k] * x;
    if(lval[k] != inf) {
      lval[k] += x;
    } else {
      ladd[k] += x;
    }
  }

  void updateall(int k, ll x) {
    max_v[k] = x; smax_v[k] = -inf;
    min_v[k] = x; smin_v[k] = inf;
    max_c[k] = min_c[k] = len[k];

    sum[k] = x * len[k];
    lval[k] = x; ladd[k] = 0;
  }

  void _add_val(ll x, int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) {
      return;
    }
    if(a <= l && r <= b) {
      addall(k, x);
      return;
    }

    push(k);
    _add_val(x, a, b, 2*k+1, l, (l+r)/2);
    _add_val(x, a, b, 2*k+2, (l+r)/2, r);
    update(k);
  }

  void _update_val(ll x, int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) {
      return;
    }
    if(a <= l && r <= b) {
      updateall(k, x);
      return;
    }

    push(k);
    _update_val(x, a, b, 2*k+1, l, (l+r)/2);
    _update_val(x, a, b, 2*k+2, (l+r)/2, r);
    update(k);
  }

  ll _query_max(int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) {
      return -inf;
    }
    if(a <= l && r <= b) {
      return max_v[k];
    }
    push(k);
    ll lv = _query_max(a, b, 2*k+1, l, (l+r)/2);
    ll rv = _query_max(a, b, 2*k+2, (l+r)/2, r);
    return max(lv, rv);
  }

  ll _query_min(int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) {
      return inf;
    }
    if(a <= l && r <= b) {
      return min_v[k];
    }
    push(k);
    ll lv = _query_min(a, b, 2*k+1, l, (l+r)/2);
    ll rv = _query_min(a, b, 2*k+2, (l+r)/2, r);
    return min(lv, rv);
  }

  ll _query_sum(int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) {
      return 0;
    }
    if(a <= l && r <= b) {
      return sum[k];
    }
    push(k);
    ll lv = _query_sum(a, b, 2*k+1, l, (l+r)/2);
    ll rv = _query_sum(a, b, 2*k+2, (l+r)/2, r);
    return lv + rv;
  }

public:
  SegmentTree(int n) {
    SegmentTree(n, nullptr);
  }

  SegmentTree(int n, ll *a) : n(n) {
    n0 = 1;
    while(n0 < n) n0 <<= 1;

    for(int i=0; i<2*n0; ++i) ladd[i] = 0, lval[i] = inf;
    len[0] = n0;
    for(int i=0; i<n0-1; ++i) len[2*i+1] = len[2*i+2] = (len[i] >> 1);

    for(int i=0; i<n; ++i) {
      max_v[n0-1+i] = min_v[n0-1+i] = sum[n0-1+i] = (a != nullptr ? a[i] : 0);
      smax_v[n0-1+i] = -inf;
      smin_v[n0-1+i] = inf;
      max_c[n0-1+i] = min_c[n0-1+i] = 1;
    }

    for(int i=n; i<n0; ++i) {
      max_v[n0-1+i] = smax_v[n0-1+i] = -inf;
      min_v[n0-1+i] = smin_v[n0-1+i] = inf;
      max_c[n0-1+i] = min_c[n0-1+i] = 0;
    }
    for(int i=n0-2; i>=0; i--) {
      update(i);
    }
  }

  // range minimize query
  void update_min(int a, int b, ll x) {
    _update_min(x, a, b, 0, 0, n0);
  }

  // range maximize query
  void update_max(int a, int b, ll x) {
    _update_max(x, a, b, 0, 0, n0);
  }

  // range add query
  void add_val(int a, int b, ll x) {
    _add_val(x, a, b, 0, 0, n0);
  }

  // range update query
  void update_val(int a, int b, ll x) {
    _update_val(x, a, b, 0, 0, n0);
  }

  // range minimum query
  ll query_max(int a, int b) {
    return _query_max(a, b, 0, 0, n0);
  }

  // range maximum query
  ll query_min(int a, int b) {
    return _query_min(a, b, 0, 0, n0);
  }

  // range sum query
  ll query_sum(int a, int b) {
    return _query_sum(a, b, 0, 0, n0);
  }
};

#define rep(i,n) for(int i=0;i<n;i++)

int main(){
    int n;
    cin >> n;
    ll c[n];
    rep(i,n)cin >> c[i];
    SegmentTree seg(n,c);
    int m;
    cin >> m;
    while(m--){
        int com,a,b,d;
        cin >> com >> a >> b >> d;
        a--;
        if(com==1){
            seg.add_val(a,b,d);
        }
        else{
            ll x=seg.query_sum(a,b);
            seg.add_val(a,b,-d);
            seg.update_max(a,b,0);
            cout << x-seg.query_sum(a,b) << '\n';
        }
    }
}
accuracy: 1
time_ms: 270
memory_kb: 35304
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using ll = long long;

template <class T> using Vec = std::vector<T>;

constexpr int INF = 1000000000;

struct Monoid {
    ll sum;
    int min, all, cnt, sec;
    Monoid() : sum(0), min(INF), all(0), cnt(0), sec(INF) {}
    Monoid(const int x) : sum(x), min(x), all(1), cnt(1), sec(INF) {}
    Monoid operator+(const Monoid& other) const {
        Monoid ret;
        ret.sum = sum + other.sum;
        ret.all = all + other.all;
        if (min < other.min) {
            ret.min = min;
            ret.cnt = cnt;
            ret.sec = std::min(sec, other.min);
        } else if (min > other.min) {
            ret.min = other.min;
            ret.cnt = other.cnt;
            ret.sec = std::min(other.sec, min);
        } else {
            ret.min = min;
            ret.cnt = cnt + other.cnt;
            ret.sec = std::min(sec, other.sec);
        }
        return ret;
    }
};

struct Effector {
    int add, lowb;
    Effector(const int add = 0, const int lowb = -INF) : add(add), lowb(lowb) {}
    Effector operator+(const Effector& other) const {
        return Effector(add + other.add, std::max((lowb == -INF ? -INF : lowb + other.add), other.lowb));
    }
};

std::optional<Monoid> mapping(Monoid m, const Effector& e) {
    if (m.all == 0) return m;
    m.sum += (ll)m.all * e.add;
    m.min += e.add;
    if (m.sec != INF) m.sec += e.add;
    if (m.min >= e.lowb) return m; 
    if (m.sec <= e.lowb) return std::nullopt;
    m.sum += (ll)m.cnt * (e.lowb - m.min);
    m.min = e.lowb;
    return m;
}

struct Segtree {
    int size, logn;
    Vec<Monoid> data;  
    Vec<Effector> lazy;

    void fetch(const int k) {
        data[k] = data[2 * k] + data[2 * k + 1];
    }

    void apply(const int k, const Effector& e) {
        if (k >= size) {
            data[k] = std::move(mapping(data[k], e).value());
        } else {
            lazy[k] = lazy[k] + e;
            const auto tmp = mapping(data[k], e);
            if (tmp) {
                data[k] = *tmp;
            } else {
                flush(k);
                fetch(k);
            }
        }
    }

    void flush(const int k) {
        apply(2 * k, lazy[k]);
        apply(2 * k + 1, lazy[k]);
        lazy[k] = Effector();
    }

    void push(const int k) {
        const int lsb = __builtin_ctz(k);
        for (int d = logn; d > lsb; --d) {
            flush(k >> d);
        }
    }

    void pull(int k) {
        k >>= __builtin_ctz(k);
        while (k > 1) {
            k >>= 1;
            fetch(k);
        }
    }

    Segtree(const Vec<Monoid>& vec) {
        const int n = (int)vec.size();
        logn = 0, size = 1;
        while (size < n) {
            logn += 1;
            size <<= 1;
        }
        data.resize(2 * size);
        lazy.resize(size);
        for (int i = 0; i < n; ++i) {
            data[i + size] = vec[i];
        }
        for (int i = size - 1; i > 0; --i) {
            fetch(i);
        }
    }

    void operate(int l, int r, const Effector& e) {
        l += size;
        r += size;
        push(l);
        push(r);
        const int lc = l, rc = r;
        while (l < r) {
            if (l & 1) apply(l++, e);
            if (r & 1) apply(--r, e);
            l >>= 1;
            r >>= 1;
        }
        pull(lc);
        pull(rc);
    }

    Monoid fold(int l, int r) {
        l += size;
        r += size;
        push(l);
        push(r);
        Monoid ret;
        while (l < r) {
            if (l & 1) ret = ret + data[l++];
            if (r & 1) ret = ret + data[--r];
            l >>= 1;
            r >>= 1;
        }
        return ret;
    }
};

int main() {
    int N;
    std::cin >> N;
    Vec<Monoid> vec(N);
    for (int i = 0; i < N; ++i) {
        int x;
        std::cin >> x;
        vec[i] = x;
    }
    Segtree seg(vec);
    int M;
    std::cin >> M;
    while (M--) {
        int t, a, b, x;
        std::cin >> t >> a >> b >> x;
        a -= 1;
        if (t == 1) {
            seg.operate(a, b, Effector(x));
        } else {
            ll ans = seg.fold(a, b).sum;
            seg.operate(a, b, Effector(-x, 0));
            ans -= seg.fold(a, b).sum;
            std::cout << ans << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 12756
final_rank: 8

code_snippet: #ifndef ATCODER_INTERNAL_BITOP_HPP
#define ATCODER_INTERNAL_BITOP_HPP 1

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

} // namespace internal

} // namespace atcoder

#endif // ATCODER_INTERNAL_BITOP_HPP
#ifndef ATCODER_LAZYSEGTREE_HPP
#define ATCODER_LAZYSEGTREE_HPP 1

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

// #include "atcoder/internal_bit"

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()>
struct lazy_segtree {
public:
    lazy_segtree() : lazy_segtree(0) {}
    lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) { update(i); }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push(r >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

protected: // Modified
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    virtual void all_apply(int k, F f) { // Modified
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};
} // namespace atcoder
#endif // ATCODER_LAZYSEGTREE_HPP

// Reference: https://atcoder.github.io/ac-library/document_ja/lazysegtree.html
//            https://betrue12.hateblo.jp/entry/2020/09/22/194541
//            https://betrue12.hateblo.jp/entry/2020/09/23/005940
/*
struct S {};
S op(S l, S r) {
    return {};
}
S e() { return {}; };
using F = bool;
S mp(F f, S x) {
    return x;
}
F composition(F fnew, F gold) { return fnew ^ gold; }
F id() { return false; }

vector<S> A;
atcoder::lazy_segtree<S, op, e, F, mp, composition, id> seg(A);
*/
template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()>
class segtree_beats : public atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> {
    using Base = atcoder::lazy_segtree<S, op, e, F, mapping, composition, id>;
    using Base::lazy_segtree;
    void all_apply(int k, F f) override {
        Base::d[k] = mapping(f, Base::d[k]);
        if (k < Base::size) {
            Base::lz[k] = composition(f, Base::lz[k]);
            if (Base::d[k].fail) Base::push(k), Base::update(k);
        }
    }
};
// Verified: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0427
namespace RangeAddChmaxRangeSum {
#include <algorithm>

template <typename Num> inline Num second_lowest(Num a, Num a2, Num c, Num c2) noexcept { // a < a2, c < c2
    return a == c ? std::min(a2, c2) : a2 <= c ? a2 : c2 <= a ? c2 : std::max(a, c);
}
using Num = int;
constexpr Num INF = 1 << 30;

struct S {
    Num lo, lo2, sum;
    unsigned sz, nlo;
    bool fail;
    S() : lo(INF), lo2(INF), sum(0), sz(0), nlo(0), fail(false) {}
    S(Num x, unsigned sz_ = 1) : lo(x), lo2(INF), sum(Num(x) * sz_), sz(sz_), nlo(sz_), fail(false) {}
};

S e() { return S(); }

S op(S l, S r) {
    S ret;
    ret.lo = std::min(l.lo, r.lo);
    ret.lo2 = second_lowest(l.lo, l.lo2, r.lo, r.lo2);
    ret.sum = l.sum + r.sum, ret.sz = l.sz + r.sz;
    ret.nlo = l.nlo * (l.lo <= r.lo) + r.nlo * (r.lo <= l.lo);
    return ret;
}

struct F {
    Num lb, bias;
    F() : lb(-INF), bias(0) {}
    F(Num chmax_, Num add) : lb(chmax_), bias(add) {}
    static F chmax(Num x) noexcept { return F(x, Num(0)); }
    static F add(Num x) noexcept { return F(-INF, x); };
};

F composition(F fnew, F fold) {
    F ret;
    ret.lb = std::max(fold.lb + fold.bias, fnew.lb) - fold.bias;
    ret.bias = fold.bias + fnew.bias;
    return ret;
}

F id() { return F(); }
S mapping(F f, S x) {
    if (x.sz == 0) return e();
    if (f.lb < x.lo2) {
        Num nxt_lo = std::max(x.lo, f.lb);
        x.sum += (nxt_lo - x.lo) * x.nlo + f.bias * x.sz;
        x.lo = nxt_lo + f.bias, x.lo2 += f.bias;
        return x;
    }
    x.fail = 1;
    return x;
}
using segtree = segtree_beats<S, op, e, F, mapping, composition, id>;
} // namespace RangeAddChmaxRangeSum
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0427"
#include <iostream>
using namespace std;

int main() {
    cin.tie(nullptr), ios::sync_with_stdio(false);

    int N, tmp;
    cin >> N;
    vector<RangeAddChmaxRangeSum::S> A(N);
    for (auto &a : A) cin >> tmp, a = tmp;

    RangeAddChmaxRangeSum::segtree segtree(A);

    int Q, q, l, r, d;
    cin >> Q;

    while (Q--) {
        cin >> q >> l >> r >> d;
        l--;
        if (q == 1) {
            segtree.apply(l, r, RangeAddChmaxRangeSum::F::add(d));
        } else {
            auto before = segtree.prod(l, r).sum;
            auto f1 = RangeAddChmaxRangeSum::F::add(-d);
            auto f2 = RangeAddChmaxRangeSum::F::chmax(0);
            segtree.apply(l, r, RangeAddChmaxRangeSum::composition(f2, f1));
            auto after = segtree.prod(l, r).sum;
            cout << before - after << '\n';
        }
    }
}
accuracy: 1
time_ms: 330
memory_kb: 12364
final_rank: 7

code_snippet: //*
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
//*/
 
#include <bits/stdc++.h>
 
// #include <atcoder/all>
 
using namespace std;
// using namespace atcoder;
 
#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define DEBUG_VEC(v) cerr<<#v<<":";for(int i=0;i<v.size();i++) cerr<<" "<<v[i]; cerr<<endl;
#define DEBUG_MAT(v) cerr<<#v<<endl;for(int i=0;i<v.size();i++){for(int j=0;j<v[i].size();j++) {cerr<<v[i][j]<<" ";}cerr<<endl;}
typedef long long ll;
// #define int ll
 
#define vi vector<int>
#define vl vector<ll>
#define vii vector< vector<int> >
#define vll vector< vector<ll> >
#define vs vector<string>
#define pii pair<int,int>
#define pis pair<int,string>
#define psi pair<string,int>
#define pll pair<ll,ll>
template<class S, class T> pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first + t.first, s.second + t.second); }
template<class S, class T> pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first - t.first, s.second - t.second); }
template<class S, class T> ostream& operator<<(ostream& os, pair<S, T> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
#define X first
#define Y second
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define rrep1(i,n) for(int i=(int)(n);i>0;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define in(x, a, b) (a <= x && x < b)
#define all(c) c.begin(),c.end()
void YES(bool t=true) {cout<<(t?"YES":"NO")<<endl;}
void Yes(bool t=true) {cout<<(t?"Yes":"No")<<endl;}
void yes(bool t=true) {cout<<(t?"yes":"no")<<endl;}
void NO(bool t=true) {cout<<(t?"NO":"YES")<<endl;}
void No(bool t=true) {cout<<(t?"No":"Yes")<<endl;}
void no(bool t=true) {cout<<(t?"no":"yes")<<endl;}
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a = b; return 1; } return 0; }
#define UNIQUE(v) v.erase(std::unique(v.begin(), v.end()), v.end());
const ll inf = 1000000001;
const ll INF = (ll)1e18 + 1;
const long double pi = 3.1415926535897932384626433832795028841971L;
int popcount(ll t) { return __builtin_popcountll(t); }
// int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
// int dx2[8] = { 1,1,0,-1,-1,-1,0,1 }, dy2[8] = { 0,1,1,1,0,-1,-1,-1 };
vi dx = {0, 1, 0, -1}, dy = {-1, 0, 1, 0};
// vi dx2 = { 1,1,0,-1,-1,-1,0,1 }, dy2 = { 0,1,1,1,0,-1,-1,-1 };
struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(25);
    }
} setup_io;
const ll MOD = 1000000007;
// const ll MOD = 998244353;
// #define mp make_pair
//#define endl '\n'


struct Node {
    ll mi1, mi2, mi_n;
    ll sum, len;
    Node(int x=0):mi1(x), mi2(inf), mi_n(1), sum(x), len(1) {}
};

struct Lazy {
    ll add, lb;
    Lazy():add(0), lb(-inf) {};
};

template <typename T1, typename T2>
class LazySegmentTree {
public:
  using F = function<T1(T1&, T1&)>; // query_func
  using G = function<T2(T2&, T2&)>; // update_func
  using H = function<T1(T1&, T2&, int, int)>; // lazy to node (node, lazy, left, right)
  int n;
  vector<T1> node;
  vector<T2> lazy;
  T1 e1;
  T2 e2;
  F query_func;
  G update_func;
  H eval_func;

  LazySegmentTree(vector<T1> a, F query_func, G update_func, H eval_func, T1 e1, T2 e2)
    :query_func(query_func), update_func(update_func), eval_func(eval_func), e1(e1), e2(e2)
  {
    int _n = a.size();
    n = 1; while (n < _n) n *= 2;
    node.resize(2 * n - 1, e1);
    lazy.resize(2 * n - 1, e2);
    for (int i = 0; i < _n; i++) node[i + n - 1] = a[i];
    for (int i = n - 2; i >= 0; i--) {
      node[i] = query_func(node[i * 2 + 1], node[i * 2 + 2]);
    }
  }

  // k�Ԗڂ̃m�[�h�ɂ��Ēx���]�����s��
  inline void eval(int k, int l, int r) {
    if (lazy[k].lb != -inf or lazy[k].add != 0) { // Change
      node[k] = eval_func(node[k], lazy[k], l, r);
      if (r - l > 1) {
        lazy[2 * k + 1] = update_func(lazy[2*k + 1], lazy[k]);
        lazy[2 * k + 2] = update_func(lazy[2*k + 2], lazy[k]);
      }
      lazy[k] = e2; // Change
    }
  }

  // [a, b)��x�ɂ���
  void update(int a, int b, T2 x, int k, int l, int r) {
    // k �Ԗڂ̃m�[�h�ɑ΂��Ēx���]�����s��
    eval(k, l, r);
    if (b <= l || r <= a) return;
    if (a <= l && r <= b) {
      lazy[k] = update_func(lazy[k], x);
      eval(k, l, r);
    }
    else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      node[k] = query_func(node[2 * k + 1], node[2 * k + 2]);
    }
  }

// [a, b)��x�ɂ���
  void update_chmax(int a, int b, T2 x, int k, int l, int r) {
    // k �Ԗڂ̃m�[�h�ɑ΂��Ēx���]�����s��
    eval(k, l, r);
    if (b <= l || r <= a || x.lb <= node[k].mi1) return;
    if (a <= l && r <= b && x.lb < node[k].mi2) {
      lazy[k] = update_func(lazy[k], x);
      eval(k, l, r);
    }
    else {
      update_chmax(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update_chmax(a, b, x, 2 * k + 2, (l + r) / 2, r);
      node[k] = query_func(node[2 * k + 1], node[2 * k + 2]);
    }
  }


  T1 query(int a, int b, int k, int l, int r) {
    eval(k, l, r);
    if (b <= l || r <= a) return e1;
    if (a <= l && r <= b) return node[k];
    T1 resl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T1 resr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return query_func(resl, resr);
  }
};

Node f(Node a, Node b) {
    Node res;
    res.sum = a.sum + b.sum;
    res.len = a.len + b.len;
    if (a.mi1 == b.mi1) {
        res.mi1 = a.mi1;
        res.mi2 = min(a.mi2, b.mi2);
        res.mi_n = a.mi_n + b.mi_n;
    }
    else {
        if (a.mi1 > b.mi1) swap(a, b);
        res.mi1 = a.mi1;
        res.mi2 = min(a.mi2, b.mi1);
        res.mi_n = a.mi_n;
    }
    return res;
}

Lazy g(Lazy a, Lazy b) {
    Lazy res;
    res.lb = max(a.lb + a.add, b.lb) - a.add;
    res.add = a.add + b.add;
    return res;
}

Node h(Node a, Lazy b, int l, int r) {
    if (b.add != 0) {
        a.sum += a.len * b.add;
        a.mi1 += b.add;
        if (a.mi2 != inf) {
            a.mi2 += b.add;
        }
        if (b.lb != -inf) {
            b.lb += b.add;
        }

        b.add = 0;
    }

    if (b.lb != -inf) {
        // DEBUG(b.lb);
        // DEBUG(pll(a.mi1, a.mi2));
        assert(a.mi2 > b.lb);
        if (a.mi1 < b.lb) {
            // assert(a.mi1 <= b.lb);
            a.sum += (b.lb - a.mi1) * a.mi_n;
            a.mi1 = b.lb;
        }
    }
    return a;
}

signed main() {
    int n, q;
    cin >> n;
    vector<Node> node(n);
    rep (i, n) {
        int x;
        cin >> x;
        node[i] = Node(x);
    }
    Node e;
    e.mi1 = -inf;
    e.mi2 = -inf + 1;
    e.sum = 0;
    e.len = 0;
    e.mi_n = 0;
    LazySegmentTree<Node, Lazy> seg(node, f, g, h, e, Lazy());

    cin >> q;
    while (q--) {
        int type;
        int l, r, x;
        cin >> type;
        cin >> l >> r >> x;
        l--;
        if (type == 1) {
            Lazy temp;
            temp.add = x;
            seg.update(l, r, temp, 0, 0, seg.n);
        }
        else {
            ll ori = seg.query(l, r, 0, 0, seg.n).sum;

            Lazy temp;
            temp.add = -x;
            seg.update(l, r, temp, 0, 0, seg.n);
            temp.add = 0;
            temp.lb = 0;
            seg.update_chmax(l, r, temp, 0, 0, seg.n);
            ll now = seg.query(l, r, 0, 0, seg.n).sum;
            
            cout << ori - now << endl;
        }
    }
}
accuracy: 1
time_ms: 440
memory_kb: 25104
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
#define rep(i,n) for(int i=0; i<(n); i++)


struct segtree {
	static const LL negInf = -1000000000000000000;
	static const LL posInf = 1000000000000000000;

	struct Node {
		LL minval, mincnt, min2, sum, add, z;
		static Node e() { return { posInf,0,posInf,0,0,0 }; }
		Node operator+(const Node& r) const {
			const Node& l = *this;
			Node res = Node::e();
			res.minval = min(l.minval, r.minval);
			res.min2 = min(l.min2, r.min2);
			res.sum = l.sum + r.sum;
			res.z = l.z + r.z;
			if (res.minval == l.minval) res.mincnt += l.mincnt; else res.min2 = min(res.min2, l.minval);
			if (res.minval == r.minval) res.mincnt += r.mincnt; else res.min2 = min(res.min2, r.minval);
			return res;
		}
	};

	int N, logN;
	vector<Node> V;

	void spread(int p) {
		if (p < N) {
			V[p * 2].sum -= V[p * 2].minval * V[p * 2].mincnt;
			V[p * 2].minval = max(V[p * 2].minval, V[p].minval - V[p * 2].add);
			V[p * 2].sum += V[p * 2].minval * V[p * 2].mincnt;
			V[p * 2].add += V[p].add;
			V[p * 2 + 1].sum -= V[p * 2 + 1].minval * V[p * 2 + 1].mincnt;
			V[p * 2 + 1].minval = max(V[p * 2 + 1].minval, V[p].minval - V[p * 2 + 1].add);
			V[p * 2 + 1].sum += V[p * 2 + 1].minval * V[p * 2 + 1].mincnt;
			V[p * 2 + 1].add += V[p].add;
		}
		if (V[p].minval != posInf) V[p].minval += V[p].add;
		if (V[p].min2 != posInf) V[p].min2 += V[p].add;
		V[p].sum += V[p].z * V[p].add;
		V[p].add = 0;
	}

	segtree(vector<LL> v) {
		N = 1; logN = 0; while (N < v.size()) { N *= 2; logN++; }
		V.assign(N * 2, Node::e());
		rep(i, v.size()) V[N + i] = { v[i],1,posInf,v[i],0,1 };
		for (int i = N - 1; i >= 1; i--) V[i] = V[i * 2] + V[i * 2 + 1];
	}

	void add(int l, int r, LL v, int a = 0, int b = 0, int i = -1) {
		if (i == -1) { a = 0; b = N; i = 1; }
		spread(i);
		if (r <= a || b <= l) return;
		if (l <= a && b <= r) { V[i].add += v; spread(i); return; }
		add(l, r, v, a, (a + b) / 2, i * 2);
		add(l, r, v, (a + b) / 2, b, i * 2 + 1);
		V[i] = V[i * 2] + V[i * 2 + 1];
	}

	LL sum(int l, int r, int a = 0, int b = 0, int i = -1) {
		if (i == -1) { a = 0; b = N; i = 1; }
		if (r <= a || b <= l) return 0;
		spread(i);
		if (l <= a && b <= r) return V[i].sum;
		LL q1 = sum(l, r, a, (a + b) / 2, i * 2);
		LL q2 = sum(l, r, (a + b) / 2, b, i * 2 + 1);
		return q1 + q2;
	}

	void chmax(int l, int r, LL v, int a = 0, int b = 0, int i = -1) {
		if (i == -1) { a = 0; b = N; i = 1; }
		spread(i);
		if (r <= a || b <= l) return;
		if (V[i].minval >= v) return;
		if (l <= a && b <= r) if (V[i].min2 > v) {
			V[i].sum += V[i].mincnt * (v - V[i].minval);
			V[i].minval = v;
			return;
		}
		chmax(l, r, v, a, (a + b) / 2, i * 2);
		chmax(l, r, v, (a + b) / 2, b, i * 2 + 1);
		V[i] = V[i * 2] + V[i * 2 + 1];
	}
};


int main() {

	int N; scanf("%d", &N);
	vector<LL> A(N); rep(i, N) scanf("%lld", &A[i]);
	segtree G(A);

	int Q; scanf("%d", &Q);
	while (Q--) {
	    int c; scanf("%d", &c);
		if (c == 1) {
		    int a, b, d; scanf("%d%d%d", &a, &b, &d); a--;
			G.add(a, b, d);
		}
		if (c == 2) {
		    int a, b, d; scanf("%d%d%d", &a, &b, &d); a--;
			LL ans = G.sum(0, N);
			G.add(a, b, -d);
			G.chmax(a, b, 0);
			ans -= G.sum(0, N);
			printf("%lld\n", ans);
		}
	}

	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 16884
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template<class T>
class SegmentTreeBeats {
    void add_(int x, T val){
        if(!val) return;
        auto& now = seg[x];
        now.sum += val*now.len;
        now.mn += val; now.mx += val; now.add += val;
        if(now.mn2 != INF<T>) now.mn2 += val;
        if(now.mx2 != -INF<T>) now.mx2 += val;
    }
    void chmin_(int x, T val){
        if(val >= seg[x].mx) return;
        auto& now = seg[x];
        now.sum += now.mxc*(val-now.mx);
        if(now.mn == now.mx) now.mn = val;
        else if(now.mn2 == now.mx) now.mn2 = val;
        now.mx = val;
    }
    void chmax_(int x, T val){
        if(val <= seg[x].mn) return;
        auto& now = seg[x];
        now.sum += now.mnc*(val-now.mn);
        if(now.mx == now.mn) now.mx = val;
        else if(now.mx2 == now.mn) now.mx2 = val;
        now.mn = val;
    }
    void get(int x){
        M& now = seg[x], &l = seg[(x<<1)|0], &r = seg[(x<<1)|1];
        now.sum = l.sum + r.sum;
        now.mn = min(l.mn, r.mn);
        now.mx = max(l.mx, r.mx);
        now.len = l.len + r.len;
        if(l.mn < r.mn) now.mnc = l.mnc, now.mn2 = min(l.mn2, r.mn);
        else if(r.mn < l.mn) now.mnc = r.mnc, now.mn2 = min(r.mn2, l.mn);
        else now.mnc = l.mnc + r.mnc, now.mn2 = min(l.mn2, r.mn2);
        if(l.mx > r.mx) now.mxc = l.mxc, now.mx2 = max(l.mx2, r.mx);
        else if(r.mx > l.mx) now.mxc = r.mxc, now.mx2 = max(r.mx2, l.mx);
        else now.mxc = l.mxc + r.mxc, now.mx2 = max(l.mx2, r.mx2);
    }
    void eval(int x){
        auto &now = seg[x];
        for (int i = 0; x < n && i < 2; ++i) {
            add_((x<<1)|i, now.add);
            chmin_((x<<1)|i, now.mx);
            chmax_((x<<1)|i, now.mn);
        }
        now.add = 0;
    }
    void thrust(int k){ for (int i = height-1; i >= 1; --i) eval(k>>i); }
    void recalc(int k) { k = k >> __builtin_ctz(k); while(k >>= 1) get(k);}

    void in_chmin(int x, T val) {
        if(seg[x].mx2 < val) chmin_(x, val);
        else {
            eval(x);
            in_chmin((x<<1)|0, val);
            in_chmin((x<<1)|1, val);
            get(x);
        }
    }
    void in_chmax(int x, T val) {
        if(seg[x].mn2 > val) chmax_(x, val);
        else {
            eval(x);
            in_chmax((x<<1)|0, val);
            in_chmax((x<<1)|1, val);
            get(x);
        }
    }
public:
#define RANGEX(NAME, INFUNC) \
void NAME(int a, int b, T val) { \
    thrust(a += n); \
    thrust(b += n); \
    for(int l = a, r = b; l < r; l >>=1, r>>=1) { \
        if (l & 1) INFUNC(l++, val); \
        if (r & 1) INFUNC(--r, val); \
    } \
    recalc(a); \
    recalc(b); \
}
    RANGEX(chmin, in_chmin)
    RANGEX(chmax, in_chmax)
    RANGEX(add, add_)
#undef RANGEX
    T sum(int a, int b) {
        thrust(a += n);
        thrust(b += n);
        T res = 0;
        for(int l = a, r = b; l < r; l >>=1, r>>=1) {
            if (l & 1) res += seg[l++].sum;
            if (r & 1) res += seg[--r].sum;
        }
        return res;
    }
    struct M {
        T sum, mx, mx2, mxc, mn, mn2, mnc, len, add;
        M() : mx2(-INF<T>), mxc(1), mn2(INF<T>), mnc(1), add(0) {};
    };
    vector<M> seg;
    int n, height;
    SegmentTreeBeats() = default;
    SegmentTreeBeats(const vector<T>& v){
        n = 1, height = 1;
        while(n < v.size()) n <<= 1, height++;
        seg.resize(2*n);
        for (int i = 0; i < v.size(); ++i) {
            seg[i+n].sum = seg[i+n].mx = seg[i+n].mn = v[i];
            seg[i+n].len = 1;
        }
        for (int i = n-1; i >= 1; --i) get(i);
    }
};

int main() {
    int n;
    cin >> n;
    vector<ll> v(n);
    for (auto &&i : v) scanf("%lld", &i);
    SegmentTreeBeats seg(v);
    int q;
    cin >> q;
    while(q--){
        int t, a, b, d; scanf("%d %d %d %d", &t, &a, &b, &d);
        a--;
        if(t == 1){
            seg.add(a, b, d);
        }else {
            ll val = seg.sum(a, b);
            seg.add(a, b, -d);
            seg.chmax(a, b, 0);
            printf("%lld\n", val-seg.sum(a, b));
        }
    }
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 22488
final_rank: 9

code_snippet: #include <iostream>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <deque>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <iomanip>
#include <map>
#include <stack>
#include <queue>
#include <functional>
#include <climits>
#include <numeric>
#include <bitset>
#include <random>
#include <tuple>
#include <initializer_list>
#include <fstream>
#include <cctype>
#include <string>
#include <cfloat>
#include <array>



class Group {
	struct Range {
		int from, until;
		bool covered_by(const Range that) const {
			return that.from <= this->from && this->until <= that.until;
		}
		bool has_intersection(const Range that) const {
			return that.from < this->until && this->from < that.until;
		}
		int length() const {
			return until - from;
		}
	};
	std::vector<int> _sum_value, _min_value, _min_count, _min_second, _add_for_all;
	std::vector<Range> area;
	std::vector<bool> is_valid;
	bool is_leaf(const int node) const {
		return (node << 1) >= _sum_value.size() || length(node) == 1;
	}
	int right(const int node) const {
		return (node << 1) + 1;
	}
	int left(const int node) const {
		return node << 1;
	}
	bool covered_by(const int node, const Range range) const {
		return area[node].covered_by(range);
	}
	bool has_intersection(const int node, const Range range) const {
		return area[node].has_intersection(range);
	}
	void add_leaf(const int node, const Range range, const int value) {
		if (covered_by(node, range)) {
			_sum_value[node] += value;
			_min_value[node] += value;
		}
	}
	void add(const int node, const Range range, const int value) {
		if (value == 0) return;
		if (is_leaf(node)) return add_leaf(node, range, value);
		if (covered_by(node, range)) {
			_add_for_all[node] += value;
		}
		else if (has_intersection(node, range)) {
			apply_min(node);
			add(left(node), range, value);
			add(right(node), range, value);
			renew_parameter(node);
		}
	}
	void change_min_leaf(const int node, const Range range, const int lower_limit) {
		if (covered_by(node, range) && _sum_value[node] < lower_limit) _sum_value[node] = _min_value[node] = lower_limit;
		else return;
	}
	void change_min(const int node, const Range range, const int lower_limit) {
		if (is_leaf(node)) return change_min_leaf(node, range, lower_limit);
		if (lower_limit <= min(node)) return;
		if (covered_by(node, range) && lower_limit < min_second(node)) {
			_sum_value[node] += (lower_limit - min(node)) * min_count(node);
			_min_value[node] = lower_limit - _add_for_all[node];
		}
		else if (has_intersection(node, range)) {
			change_min(left(node), range, lower_limit - _add_for_all[node]);
			change_min(right(node), range, lower_limit - _add_for_all[node]);
			renew_parameter(node);
		}
	}
	int min(const int node) const {
		return _min_value[node] + _add_for_all[node];
	}
	int min_count(const int node) const {
		return _min_count[node];
	}
	int min_second(const int node) const {
		return _min_second[node] + _add_for_all[node];
	}
	int length(const int node) const {
		return area[node].length();
	}
	int sum_all(const int node) const {
		return _sum_value[node] + _add_for_all[node] * length(node);
	}
	int sum_leaf(const int node, const Range range) {
		if (covered_by(node, range)) return _sum_value[node];
		else return 0;
	}
	int sum(const int node, const Range range) {
		if (is_leaf(node)) return sum_leaf(node, range);
		if (covered_by(node, range)) {
			return sum_all(node);
		}
		else if (has_intersection(node, range)) {
			apply_change(node);
			renew_parameter(node);
			return sum(left(node), range) + sum(right(node), range);
		}
		else return 0;
	}
	void apply_change(const int node) {
		apply_min(node);
		if (_add_for_all[node] != 0) {
			add(left(node), area[node], _add_for_all[node]);
			add(right(node), area[node], _add_for_all[node]);
			_add_for_all[node] = 0;
		}
	}
	void apply_min(const int node) {
		change_min(left(node), area[node], _min_value[node]);
		change_min(right(node), area[node], _min_value[node]);
	}
	void renew_parameter(const int node) {
		_min_value[node] = std::min(min(left(node)), min(right(node)));
		_min_count[node] = 0;
		_min_second[node] = INT_MAX >> 1;
		if (_min_value[node] == min(left(node))) {
			_min_count[node] += min_count(left(node));
			_min_second[node] = std::min(_min_second[node], min_second(left(node)));
		}
		else _min_second[node] = std::min(_min_second[node], min(left(node)));
		if (_min_value[node] == min(right(node))) {
			_min_count[node] += min_count(right(node));
			_min_second[node] = std::min(_min_second[node], min_second(right(node)));
		}
		else _min_second[node] = std::min(_min_second[node], min(right(node)));
		_sum_value[node] = sum_all(left(node)) + sum_all(right(node));
	}
	void initialize(const int node) {
		if ((node << 1) >= _sum_value.size()) return;
		initialize(node << 1); initialize((node << 1) + 1);
		if (is_valid[node << 1] || is_valid[(node << 1) + 1]) {
			is_valid[node] = true;
			area[node] = area[node << 1];
			if (is_valid[(node << 1) + 1]) area[node].until = area[(node << 1) + 1].until;
			if (area[node].length() == 1) {
				_sum_value[node] = _min_value[node] = _sum_value[node << 1];
				_min_count[node] = 1;
				_min_second[node] = INT_MAX >> 1;
			}
			else {
				renew_parameter(node);
			}
		}
	}
public:
	Group(const std::vector<int>& initial) {
		int len = 1;
		while (len < initial.size()) len <<= 1;
		len;
		_sum_value = _min_value = _min_count = _min_second = _add_for_all = std::vector<int>(len << 1, 0);
		area = std::vector<Range>(len << 1);
		is_valid = std::vector<bool>(len << 1, false);
		for (auto i = 0; i < initial.size(); ++i) {
			_sum_value[i + len] = _min_value[i + len] = initial[i];
			_min_count[i + len] = 1;
			_min_second[i + len] = INT_MAX >> 1;
			area[i + len] = Range{ i, i + 1 };
			is_valid[i + len] = true;
		}
		initialize(1);
	}
	void add(int from, int until, int value) {
		add(1, Range{ from, until }, value);
	}
	int emerge(int from, int until, int max) {
		const auto current = sum_all(1);
		add(1, Range{ from, until }, -max);
		change_min(1, Range{ from, until }, 0);
		return current - sum_all(1);
	}
};
int main() {
	int n; std::cin >> n;
	std::vector<int> initial(n); for (auto& c : initial) std::cin >> c;
	Group g(initial);
	int m; std::cin >> m;
	for (auto i = 0; i < m; ++i) {
		int t, a, b, d; std::cin >> t >> a >> b >> d;
		switch (t) {
		case 1: g.add(a - 1, b, d); break;
		case 2: std::cout << g.emerge(a - 1, b, d) << std::endl; break;
		default: throw 0;
		}
	}
}
accuracy: 1
time_ms: 320
memory_kb: 10588
final_rank: 5

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define NUM 100005

struct Info{

	ll range_sum,
	   uniformity,
	   minimum,
	   second_minimum,
	   num_minimum,
	   base_value;
};

ll N = 1;
Info info[8*NUM];

void init(ll first_N){
	while(N < first_N)N *= 2;
}

void updateInfo(int node_id){

	int left_child = 2*node_id+1;
	int right_child = 2*node_id+2;

	info[node_id].range_sum = info[left_child].range_sum+info[right_child].range_sum;

	if(info[left_child].minimum < info[right_child].minimum){

		info[node_id].minimum = info[left_child].minimum;
		info[node_id].num_minimum = info[left_child].num_minimum;
		info[node_id].second_minimum = min(info[left_child].second_minimum,info[right_child].minimum);

	}else if(info[left_child].minimum > info[right_child].minimum){

		info[node_id].minimum = info[right_child].minimum;
		info[node_id].num_minimum = info[right_child].num_minimum;
		info[node_id].second_minimum = min(info[right_child].second_minimum,info[left_child].minimum);

	}else{ //info[left_child].minimum == info[right_child].minimum

		info[node_id].minimum = info[left_child].minimum;
		info[node_id].num_minimum = info[left_child].num_minimum+info[right_child].num_minimum;
		info[node_id].second_minimum = min(info[left_child].second_minimum,info[right_child].second_minimum);
	}
}

void first_add(int loc,ll value){
	loc += N-1;

	info[loc].range_sum = value;
	info[loc].minimum = value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		updateInfo(parent);

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}


void evaluate(ll node_id,ll node_left,ll node_right){

	ll left_child = 2*node_id+1;
	ll right_child = 2*node_id+2;

	if(info[node_id].uniformity != 0){

		info[node_id].minimum += info[node_id].uniformity;
		if(info[node_id].second_minimum != HUGE_NUM){

			info[node_id].second_minimum += info[node_id].uniformity;
		}

		info[node_id].range_sum += (node_right-node_left)*info[node_id].uniformity;

		if(node_id <= N-2){

			info[left_child].uniformity += info[node_id].uniformity;
			info[right_child].uniformity += info[node_id].uniformity;

			if(info[left_child].base_value != -1){

				info[left_child].base_value += info[node_id].uniformity;
			}
			if(info[right_child].base_value != -1){

				info[right_child].base_value += info[node_id].uniformity;
			}
		}

		info[node_id].uniformity = 0;
	}

	if(info[node_id].base_value != -1){

		if(info[node_id].base_value >= info[node_id].second_minimum){

			info[left_child].base_value = max(info[left_child].base_value,info[node_id].base_value);
			info[right_child].base_value = max(info[right_child].base_value,info[node_id].base_value);

			if(node_id < N-1){
				evaluate(left_child,node_left,(node_left+node_right)/2);
				evaluate(right_child,(node_left+node_right)/2,node_right);

				updateInfo(node_id);
			}

		}else if(info[node_id].base_value > info[node_id].minimum){

			info[node_id].range_sum += (info[node_id].base_value-info[node_id].minimum)*info[node_id].num_minimum;
			info[node_id].minimum = info[node_id].base_value;

			if(node_id < N-1){

				info[left_child].base_value = max(info[left_child].base_value,info[node_id].base_value);
				info[right_child].base_value = max(info[right_child].base_value,info[node_id].base_value);
			}
		}
		info[node_id].base_value = -1;
	}
}


void changeMax(ll left,ll right,ll value,ll node_id,ll node_left,ll node_right){

	evaluate(node_id,node_left,node_right);

	if(right <= node_left || left >= node_right){
		return;
	}
	else if(left <= node_left && right >= node_right){

		info[node_id].base_value = value;
		evaluate(node_id,node_left,node_right);

	}else{

		changeMax(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		changeMax(left,right,value, 2*node_id+2,(node_left+node_right)/2,node_right);
		updateInfo(node_id);
	}
}

void add(ll left,ll right,ll value,ll node_id,ll node_left,ll node_right){

	evaluate(node_id,node_left,node_right);

	if(right <= node_left || left >= node_right){
		return;
	}
	else if(left <= node_left && right >= node_right){

		info[node_id].uniformity += value;
		evaluate(node_id,node_left,node_right);

	}else{

		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		add(left,right,value, 2*node_id+2,(node_left+node_right)/2,node_right);
		updateInfo(node_id);
	}

}

ll getSum(ll left,ll right,ll node_id,ll node_left,ll node_right){

	evaluate(node_id,node_left,node_right);

	if(right <= node_left || left >= node_right){
		return 0;

	}else if(left <= node_left && right >= node_right){

		return info[node_id].range_sum;

	}else{

		ll ret = 0;

		ret += getSum(left,right,2*node_id+1,node_left,(node_left+node_right)/2);
		ret += getSum(left,right,2*node_id+2,(node_left+node_right)/2,node_right);

		return ret;
	}
}



int main(){

	ll first_N;
	scanf("%lld",&first_N);

	init(first_N);

	for(ll i = 0; i <= 2*N-2; i++){
		info[i].range_sum = 0;
		info[i].uniformity = 0;
		info[i].minimum = HUGE_NUM;
		info[i].num_minimum = 1;
		info[i].second_minimum = HUGE_NUM;
		info[i].base_value = -1;
	}

	ll tmp;
	for(int i = 0; i < first_N; i++){

		scanf("%lld",&tmp);
		first_add(i,tmp);
	}

	int num_query;
	scanf("%d",&num_query);

	int command,left,right;
	ll value,pre,current;

	for(int loop = 0; loop < num_query; loop++){

		scanf("%d %d %d %lld",&command,&left,&right,&value);
		left--;
		right--;

		if(command == 1){ //加算命令

			add(left,right+1,value,0,0,N);

		}else{

			pre = getSum(0,N,0,0,N);
			add(left,right+1,-value,0,0,N);
			changeMax(left,right+1,0,0,0,N);
			current = getSum(0,N,0,0,N);

			printf("%lld\n",pre-current);
		}
	}

	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 15492
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int mod=1000000007,MAX=1<<18;
const ll INF=1LL<<60;

int n;
ll max_fi[2*MAX-1],max_se[2*MAX-1],max_cnt[2*MAX-1];
ll min_fi[2*MAX-1],min_se[2*MAX-1],min_cnt[2*MAX-1];
ll sum[2*MAX-1];
ll lazyadd[2*MAX-1],lazyupdate[2*MAX-1];
bool done[2*MAX-1];

void init(int n_){
    n=1;
    while(n<n_) n*=2;
    
    for(int i=0;i<2*n-1;i++){
        max_fi[i]=-INF;
        max_se[i]=-INF;
        max_cnt[i]=n;
        
        min_fi[i]=INF;
        min_se[i]=INF;
        min_cnt[i]=n;
        
        sum[i]=0;
    }
}

void update_node_max(ll x,int k){
    sum[k]+=(x-max_fi[k])*max_cnt[k];
    
    if(max_fi[k]==min_fi[k]){
        max_fi[k]=min_fi[k]=x;
    }else if(max_fi[k]==min_se[k]){
        max_fi[k]=min_se[k]=x;
    }else{
        max_fi[k]=x;
    }
    
    if(done[k]){
        lazyupdate[k]=min(lazyupdate[k],x);
    }
}

void update_node_min(ll x,int k){
    sum[k]+=(x-min_fi[k])*min_cnt[k];
    
    if(min_fi[k]==max_fi[k]){
        min_fi[k]=max_fi[k]=x;
    }else if(min_fi[k]==max_se[k]){
        min_fi[k]=max_se[k]=x;
    }else{
        min_fi[k]=x;
    }
    
    if(done[k]){
        lazyupdate[k]=max(lazyupdate[k],x);
    }
}

void update_node_(ll x,int k,int l,int r){
    max_fi[k]=x;
    max_se[k]=-INF;
    max_cnt[k]=r-l;
    
    min_fi[k]=x;
    min_se[k]=INF;
    min_cnt[k]=r-l;
    
    sum[k]=x*(r-l);
    
    lazyupdate[k]=x;
    done[k]=1;
    lazyadd[k]=0;
}

void update_node_add(ll x,int k,int l,int r){
    max_fi[k]+=x;
    if(max_se[k]!=-INF) max_se[k]+=x;
    
    min_fi[k]+=x;
    if(min_se[k]!=INF) min_se[k]+=x;
    
    sum[k]+=x*(r-l);
    
    if(done[k]){
        lazyupdate[k]+=x;
    }else{
        lazyadd[k]+=x;
    }
}

void eval(int k,int l,int r){
    
    if(l+1>=r) return;
    
    if(done[k]){
        update_node_(lazyupdate[k],2*k+1,l,(l+r)/2);
        update_node_(lazyupdate[k],2*k+2,(l+r)/2,r);
        done[k]=0;
        return;
    }
    
    if(lazyadd[k]){
        update_node_add(lazyadd[k],2*k+1,l,(l+r)/2);
        update_node_add(lazyadd[k],2*k+2,(l+r)/2,r);
        lazyadd[k]=0;
    }
    
    if(max_fi[k]<max_fi[2*k+1]){
        update_node_max(max_fi[k],2*k+1);
    }
    if(min_fi[k]>min_fi[2*k+1]){
        update_node_min(min_fi[k],2*k+1);
    }
    if(max_fi[k]<max_fi[2*k+2]){
        update_node_max(max_fi[k],2*k+2);
    }
    if(min_fi[k]>min_fi[2*k+2]){
        update_node_min(min_fi[k],2*k+2);
    }
}

void merge(int k){
    sum[k]=sum[2*k+1]+sum[2*k+2];
    
    if(max_fi[2*k+1]>max_fi[2*k+2]){
        max_fi[k]=max_fi[2*k+1];
        max_cnt[k]=max_cnt[2*k+1];
        max_se[k]=max(max_se[2*k+1],max_fi[2*k+2]);
    }else if(max_fi[2*k+1]<max_fi[2*k+2]){
        max_fi[k]=max_fi[2*k+2];
        max_cnt[k]=max_cnt[2*k+2];
        max_se[k]=max(max_fi[2*k+1],max_se[2*k+2]);
    }else{
        max_fi[k]=max_fi[2*k+1];
        max_cnt[k]=max_cnt[2*k+1]+max_cnt[2*k+2];
        max_se[k]=max(max_se[2*k+1],max_se[2*k+2]);
    }
    
    if(min_fi[2*k+1]<min_fi[2*k+2]){
        min_fi[k]=min_fi[2*k+1];
        min_cnt[k]=min_cnt[2*k+1];
        min_se[k]=min(min_se[2*k+1],min_fi[2*k+2]);
    }else if(min_fi[2*k+1]>min_fi[2*k+2]){
        min_fi[k]=min_fi[2*k+2];
        min_cnt[k]=min_cnt[2*k+2];
        min_se[k]=min(min_fi[2*k+1],min_se[2*k+2]);
    }else{
        min_fi[k]=min_fi[2*k+1];
        min_cnt[k]=min_cnt[2*k+1]+min_cnt[2*k+2];
        min_se[k]=min(min_se[2*k+1],min_se[2*k+2]);
    }
}

void update_chmax(int a,int b,ll x,int k,int l,int r){
    
    eval(k,l,r);
    
    if(r<=a||b<=l||min_fi[k]>=x) return;
    
    if(a<=l&&r<=b&&min_se[k]>x){
        update_node_min(x,k);
        eval(k,l,r);
    }else{
        update_chmax(a,b,x,2*k+1,l,(l+r)/2);
        update_chmax(a,b,x,2*k+2,(l+r)/2,r);
        
        merge(k);
    }
}

void update_chmin(int a,int b,ll x,int k,int l,int r){
    
    eval(k,l,r);
    
    if(r<=a||b<=l||max_fi[k]<=x) return;
    
    if(a<=l&&r<=b&&max_se[k]<x){
        update_node_max(x,k);
        eval(k,l,r);
    }else{
        update_chmin(a,b,x,2*k+1,l,(l+r)/2);
        update_chmin(a,b,x,2*k+2,(l+r)/2,r);
        
        merge(k);
    }
}

void update(int a,int b,ll x,int k,int l,int r){
    eval(k,l,r);
    
    if(r<=a||b<=l) return;
    
    if(a<=l&&r<=b){
        update_node_(x,k,l,r);
        eval(k,l,r);
    }else{
        update(a,b,x,2*k+1,l,(l+r)/2);
        update(a,b,x,2*k+2,(l+r)/2,r);
        
        merge(k);
    }
}

void add(int a,int b,ll x,int k,int l,int r){
    eval(k,l,r);
    
    if(r<=a||b<=l) return;
    
    if(a<=l&&r<=b){
        update_node_add(x,k,l,r);
        eval(k,l,r);
    }else{
        add(a,b,x,2*k+1,l,(l+r)/2);
        add(a,b,x,2*k+2,(l+r)/2,r);
        
        merge(k);
    }
}

ll query_sum(int a,int b,int k,int l,int r){
    
    if(r<=a||b<=l) return 0;
    
    eval(k,l,r);
    
    if(a<=l&&r<=b) return sum[k];
    
    ll vl=query_sum(a,b,2*k+1,l,(l+r)/2);
    ll vr=query_sum(a,b,2*k+2,(l+r)/2,r);
    return vl+vr;
}

ll query_max(int a,int b,int k,int l,int r){
    
    if(r<=a||b<=l) return -INF;
    
    eval(k,l,r);
    
    if(a<=l&&r<=b) return max_fi[k];
    
    ll vl=query_max(a,b,2*k+1,l,(l+r)/2);
    ll vr=query_max(a,b,2*k+2,(l+r)/2,r);
    return max(vl,vr);
}

ll query_min(int a,int b,int k,int l,int r){
    
    if(r<=a||b<=l) return INF;
    
    eval(k,l,r);
    
    if(a<=l&&r<=b) return min_fi[k];
    
    ll vl=query_min(a,b,2*k+1,l,(l+r)/2);
    ll vr=query_min(a,b,2*k+2,(l+r)/2,r);
    return min(vl,vr);
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    /*int N,Q;cin>>N>>Q;
    init(N);
    
    for(int i=0;i<N;i++){
        ll x;cin>>x;
        update(i,i+1,x,0,0,n);
    }
    
    while(Q--){
        int t;cin>>t;
        if(t==0){
            int a,b;ll x;cin>>a>>b>>x;
            update_chmin(a,b,x,0,0,n);
        }else if(t==1){
            int a,b;ll x;cin>>a>>b>>x;
            update_chmax(a,b,x,0,0,n);
        }else if(t==2){
            int a,b;ll x;cin>>a>>b>>x;
            add(a,b,x,0,0,n);
        }else{
            int a,b;cin>>a>>b;
            cout<<query_sum(a,b,0,0,n)<<endl;
        }
    }*/
    
    int N;cin>>N;
    init(N);
    
    for(int i=0;i<N;i++){
        ll x;cin>>x;
        update(i,i+1,x,0,0,n);
    }
    
    int Q;cin>>Q;
    while(Q--){
        int t,a,b;ll x;
        cin>>t>>a>>b>>x;
        a--;
        
        if(t==1){
            add(a,b,x,0,0,n);
        }else{
            ll fi=query_sum(0,n,0,0,n);
            add(a,b,-x,0,0,n);
            update_chmax(a,b,0,0,0,n);
            ll se=query_sum(0,n,0,0,n);
            
            cout<<fi-se<<endl;
        }
    }
    
}
accuracy: 1
time_ms: 480
memory_kb: 20032
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
using i64 = long long;
const i64 MOD = 1e9+7;
const i64 INF = 1e18+7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}

template <typename T, typename U = int>
struct Node{

    using np = Node<T, U>*;

    static np nil;

    T val;
    U lazy;
    uint32_t pri;

    int size;
    T sum;

    np l = nil;
    np r = nil;

    Node(T v, U OU = U()) : val(v), lazy(OU), pri(rndpri()), size(1), sum(v), l(nil), r(nil){}
    Node(T v, U OU, uint32_t p) : val(v), lazy(OU), pri(p), size(1), sum(v), l(nil), r(nil){}

    static uint32_t rndpri() {
        static uint32_t x = 123456789, y = 362436069, z = 521288629, w = time(0);
        uint32_t t = x ^ (x << 11);
        x = y;
        y = z;
        z = w;
        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
        return max<uint32_t>(1, w & 0x3FFFFFFF);
    }
};


template <typename T, typename U = int>
class Treap{

    using nt = Node<T, U>;
    using np = nt*;
    using F = function<T(T, T)>;
    using G = function<T(T, U, int)>;
    using H = function<U(U, U)>;

public:

    np root;
    bool is_list;
    F f;
    G g;
    H h;
    T OT;
    U OU;

    Treap(bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    Treap(T val, bool is_list, F f, G g, H h, T OT, U OU) : root(new nt(val)), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    // 配列で初期化する
    Treap(vector<T> v, bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){
        sort(v.begin(), v.end());
        for(auto& x : v)
            push_back(x);
    }

    static Treap make(bool is_list, F f = [](T x, T){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(is_list, f, g, h, OT, OU);
    }

    static Treap make(T val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    static Treap make(vector<T>& val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    ~Treap(){
        /*
        clear();
        if(root != nt::nil)
            delete root;
        */
    }

    int _size(np x){return x == nt::nil ? 0 : x->size;}
    T _sum(np x){return x == nt::nil ? OT : x->sum;}

    np _update(np x){

        if(x == nt::nil)
            return x;

        if(is_list){
            _push(x);
            _push(x->l);
            _push(x->r);
        }

  x->sum = f(f(_sum(x->l), x->val), _sum(x->r));
  x->size = _size(x->l) + _size(x->r) + 1;
        return x;
    }

    void _push(np x){
        if(x->lazy == OU)
            return ;

        x->sum = g(x->sum, x->lazy, x->size);
        x->val = g(x->val, x->lazy, 1);

        if(x->l != nt::nil)
            x->l->lazy = h(x->l->lazy, x->lazy);
        if(x->r != nt::nil)
            x->r->lazy = h(x->r->lazy, x->lazy);

        x->lazy = OU;

    }

    np _merge(np l, np r){
        if(l == nt::nil || r ==nt::nil)
            return l == nt::nil ? r : l;

        if(l->pri > r->pri){
            l->r = _merge(l->r, r);
            return _update(l);
        }else{
            r->l = _merge(l, r->l);
            return _update(r);
        }
    }

    pair<np,np> _split(np x, int k){
        if(x == nt::nil)
            return make_pair(nt::nil, nt::nil);

        assert(0 <= k && k <= _size(x));

        if(k <= _size(x->l)){
            pair<np, np> s = _split(x->l, k);
            x->l = s.second;
            return make_pair(s.first, _update(x));

        }else{
            pair<np, np> s = _split(x->r, k - _size(x->l) - 1);
            x->r = s.first;
            return make_pair(_update(x), s.second);
        }
    }

    np _insert(np x, int k, T val){
        np l, r;
        tie(l, r) = _split(x, k);
        return _merge(_merge(l, new nt(val, OU)), r);
    }

    np _erase(np x, int k){
        np l, r, m;
        tie(l, r) = _split(x, k);
        tie(m, r) = _split(r, 1);
        if(m != nt::nil)
            delete m;
        return _merge(l, r);
    }

    void _set(np x, int k, T val){
        _update(x);

        if(k < _size(x->l))
            _set(x->l, k, val);
        else if(_size(x->l) == k)
            x->val = val;
        else
            _set(x->r, k - _size(x->l) - 1, val);

        _update(x);
    }

    void _add(np x, int l, int r, U val){
        _update(x);

        if(x == nt::nil)
            return ;
        l = max(l, 0);
        r = min(r, _size(x));

        int sl = _size(x->l);

        if(l >= r)
            return ;

        if (l == 0 && r == _size(x)){
            x->lazy = h(x->lazy, val);
        }
        else{
            if(l <= sl && sl < r)
                x->val = g(x->val, val, 1);

            _add(x->l, l, r, val);
            _add(x->r, l - sl - 1, r - sl - 1, val);
        }

        _update(x);
    }

    np _getnode(np x, int k){

        _update(x);

        assert(0 <= k && k < _size(x));

        if(k < _size(x->l))
            return _getnode(x->l, k);
        else if(_size(x->l) == k)
            return x;
        else
            return _getnode(x->r, k - _size(x->l) - 1);
    }

    T _get(np x, int k){
        return _getnode(x, k)->val;
    }

    T _rangesum(np x, int l, int r){
        _update(x);

        l = max(l, 0);
        r = min(r, _size(x));
        if(l >= r)
            return OT;
        if(l == 0 && r == _size(x))
            return _sum(x);

        int sl = _size(x->l);
        T ret = (l <= sl && sl < r ? x->val : OT);
        ret = f(_rangesum(x->l, l, r), ret);
        ret = f(ret, _rangesum(x->r, l - sl - 1, r - sl - 1));
        return ret;
    }

    int _lowerbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val <= x->val)
            return _lowerbound(x->l, val);
        else
            return _lowerbound(x->r,val) + _size(x->l) + 1;
    }

    int _upperbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val < x->val)
            return _upperbound(x->l, val);
        else
            return _upperbound(x->r,val) + _size(x->l) + 1;
    }

    np _insert(np x, T val){
        return _insert(x, _lowerbound(x, val), val);
    }

    void _clear(np x){
        if(x == nullptr || x == nt::nil)
            return;
        if(x->l != nt::nil){
            _clear(x->l);
            delete(x->l);
            x->l = nt::nil;
        }
        if(x->r != nt::nil){
            _clear(x->r);
            delete(x->r);
            x->r = nt::nil;
        }
    }

    void push_front(T val){
        root = _merge(new nt(val, OU), root);
    }

    void push_back(T val){
        root = _merge(root, new nt(val,OU));
    }

    void pop_front(){
        root = _split(root, 1).second;
    }

    void pop_back(){
        root = _split(root, _size(root) - 1).first;
    }

    // [0, k)と[k, size)に分割して, [k, size)側を返す
    Treap split_left(int k){
        np p;
        tie(root, p) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // [0, k)と[k, size)に分割して, [0, k)側を返す
    Treap split_right(int k){
        np p;
        tie(p, root) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // rootを含めたサイズの出力
    int size(){
        return (root == nt::nil ? 0 : root->size);
    }

    // k番目への代入
    void set(int k, T val){
        return _set(root, k, val);
    }

    // k番目への加算
    void add(int k, U val){
        assert(is_list);
        return _add(root, k, k + 1, val);
    }

    // [l, r)への一様加算
    void add(int l, int r, U val){
        return _add(root, l, r, val);
    }

    // k番目の取得
    T get(int k){
        return _get(root, k);
    }

    // [l, r)の総和 (同様の実装でRMQ等も可能)
    T get(int l, int r){
        return _rangesum(root, l, r);
    }

    // k番目への挿入
    void insert(int k, T val){
        assert(is_list);
        root = _insert(root, k, val);
    }

    // 適切な位置への挿入
    void insert(T val){
        root = _insert(root, val);
    }

    // val <= get(k) となるような最小のk
    int lowerbound(T val){
        return _lowerbound(root, val);
    }

    // val < get(k) となるような最小のk
    int upperbound(T val){
        return _upperbound(root, val);
    }

    // k番目の要素削除
    void erase(int k){
        root = _erase(root, k);
    }

    // 要素の全削除
    void clear(){
        if(root != nullptr && root != nt::nil){
            _clear(root);
            delete(root);
            root = nt::nil;
        }
    }
};

using node_type = Node<i64, pair<i64, bool>>;
template<> node_type* node_type::nil = new node_type(0, make_pair(0, false), 0);


signed main(){
    int n;
    cin >> n;
    vector<int> a(n);
    for(auto& x : a)
        cin >> x;
    int m;
    cin >> m;

    constexpr int packet = 20;
    constexpr int size = (100100) / packet;

    auto f = [&](auto x, auto y){
        if(x.second != y.second)
            return y;
        if(y.second)
            return y;
        return make_pair(x.first + y.first, false);
    };

    vector<Treap<i64, pair<i64, bool>>> tr;
    vector<vector<i64>> elm_idxes(size, vector<i64>(packet));
    for(int i = 0; i < size; ++i){
        int st = packet * i;
        int en = packet * (i + 1);
        vector<i64> e;
        vector<pair<int,int>> v;
        for(int j = st; j < en; ++j){
            e.emplace_back(j < n ? a[j] : 1e9);
            v.emplace_back(e.back(), j - st);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[i][j] = v[j].second;
        auto t = Treap<i64, pair<i64, bool>>::make(e, false, [](auto x, auto y){return x + y;}, 0, [](auto x, auto y, int){return y.second ? 0 : x + y.first;}, f, make_pair(0, false));
        tr.emplace_back(move(t));
    }

    auto get_raw = [&](int idx){
        vector<i64> ret(packet, 0);
        for(int i = 0; i < packet; ++i){
            ret[elm_idxes[idx][i]] = max(0LL, tr[idx].get(i));
        }
        return ret;
    };

    auto rebuild = [&](int idx, std::vector<i64>& elm){
        while(tr[idx].size())
            tr[idx].erase(0);
        vector<pair<int,int>> v;
        for(int j = 0; j < packet; ++j){
            v.emplace_back(elm[j], j);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[idx][j] = v[j].second;
        for(auto& x : elm)
            tr[idx].insert(x);
    };


    for(int _ = 0; _ < m; ++_){
        i64 type, l, r, d;
        cin >> type >> l >> r >> d;
        --l;
        int l_idx = l / packet;
        int r_idx = r / packet;
        int l_mod = l % packet;
        int r_mod = r % packet;
        if(type == 1){
            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i)
                    elm[i] += d;
                rebuild(l_idx, elm);
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i)
                l_elm[i] += d;
            rebuild(l_idx, l_elm);

            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i)
                r_elm[i] += d;
            rebuild(r_idx, r_elm);

            for(int i = l_idx + 1; i < r_idx; ++i)
                tr[i].add(0, packet, make_pair(d, false));
        }
        else{
            i64 ans = 0;

            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i){
                    ans += min(elm[i], d);
                    elm[i] = max(0LL, elm[i] - d);
                }
                rebuild(l_idx, elm);
                cout << ans << endl;
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i){
                ans += min(l_elm[i], d);
                l_elm[i] = max(0LL, l_elm[i] - d);
            }
            rebuild(l_idx, l_elm);

            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i){
                ans += min(r_elm[i], d);
                r_elm[i] = max(0LL, r_elm[i] - d);
            }
            rebuild(r_idx, r_elm);

            for(int i = l_idx + 1; i < r_idx; ++i){
                int l_bound = tr[i].lowerbound(0);
                int r_bound = tr[i].lowerbound(d);
                ans += tr[i].get(l_bound, r_bound);
                ans += (packet - r_bound) * d;
                tr[i].add(0, r_bound, make_pair(0, true));
                tr[i].add(r_bound, packet, make_pair(-d, false));

            }
            cout << ans << endl;
        }
    }
}
accuracy: 0.175
time_ms: 10
memory_kb: 10756
final_rank: 19

code_snippet: #include "bits/stdc++.h"
using namespace std;
using i64 = long long;
const i64 MOD = 1e9+7;
const i64 INF = 1e18+7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}

template <typename T, typename U = int>
struct Node{

    using np = Node<T, U>*;

    static np nil;

    T val;
    U lazy;
    uint32_t pri;

    int size;
    T sum;

    np l = nil;
    np r = nil;

    Node(T v, U OU = U()) : val(v), lazy(OU), pri(rndpri()), size(1), sum(v), l(nil), r(nil){}
    Node(T v, U OU, uint32_t p) : val(v), lazy(OU), pri(p), size(1), sum(v), l(nil), r(nil){}

    static uint32_t rndpri() {
        static uint32_t x = 123456789, y = 362436069, z = 521288629, w = time(0);
        uint32_t t = x ^ (x << 11);
        x = y;
        y = z;
        z = w;
        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
        return max<uint32_t>(1, w & 0x3FFFFFFF);
    }
};


template <typename T, typename U = int>
class Treap{

    using nt = Node<T, U>;
    using np = nt*;
    using F = function<T(T, T)>;
    using G = function<T(T, U, int)>;
    using H = function<U(U, U)>;

public:

    np root;
    bool is_list;
    F f;
    G g;
    H h;
    T OT;
    U OU;

    Treap(bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    Treap(T val, bool is_list, F f, G g, H h, T OT, U OU) : root(new nt(val)), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    // 配列で初期化する
    Treap(vector<T> v, bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){
        sort(v.begin(), v.end());
        for(auto& x : v)
            push_back(x);
    }

    static Treap make(bool is_list, F f = [](T x, T){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(is_list, f, g, h, OT, OU);
    }

    static Treap make(T val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    static Treap make(vector<T>& val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    ~Treap(){
        /*
        clear();
        if(root != nt::nil)
            delete root;
        */
    }

    int _size(np x){return x == nt::nil ? 0 : x->size;}
    T _sum(np x){return x == nt::nil ? OT : x->sum;}

    np _update(np x){

        if(x == nt::nil)
            return x;

        if(is_list){
            _push(x);
            _push(x->l);
            _push(x->r);
        }

  x->sum = f(f(_sum(x->l), x->val), _sum(x->r));
  x->size = _size(x->l) + _size(x->r) + 1;
        return x;
    }

    void _push(np x){
        if(x->lazy == OU)
            return ;

        x->sum = g(x->sum, x->lazy, x->size);
        x->val = g(x->val, x->lazy, 1);

        if(x->l != nt::nil)
            x->l->lazy = h(x->l->lazy, x->lazy);
        if(x->r != nt::nil)
            x->r->lazy = h(x->r->lazy, x->lazy);

        x->lazy = OU;

    }

    np _merge(np l, np r){
        if(l == nt::nil || r ==nt::nil)
            return l == nt::nil ? r : l;

        if(l->pri > r->pri){
            l->r = _merge(l->r, r);
            return _update(l);
        }else{
            r->l = _merge(l, r->l);
            return _update(r);
        }
    }

    pair<np,np> _split(np x, int k){
        if(x == nt::nil)
            return make_pair(nt::nil, nt::nil);

        assert(0 <= k && k <= _size(x));

        if(k <= _size(x->l)){
            pair<np, np> s = _split(x->l, k);
            x->l = s.second;
            return make_pair(s.first, _update(x));

        }else{
            pair<np, np> s = _split(x->r, k - _size(x->l) - 1);
            x->r = s.first;
            return make_pair(_update(x), s.second);
        }
    }

    np _insert(np x, int k, T val){
        np l, r;
        tie(l, r) = _split(x, k);
        return _merge(_merge(l, new nt(val, OU)), r);
    }

    np _erase(np x, int k){
        np l, r, m;
        tie(l, r) = _split(x, k);
        tie(m, r) = _split(r, 1);
        if(m != nt::nil)
            delete m;
        return _merge(l, r);
    }

    void _set(np x, int k, T val){
        _update(x);

        if(k < _size(x->l))
            _set(x->l, k, val);
        else if(_size(x->l) == k)
            x->val = val;
        else
            _set(x->r, k - _size(x->l) - 1, val);

        _update(x);
    }

    void _add(np x, int l, int r, U val){
        _update(x);

        if(x == nt::nil)
            return ;
        l = max(l, 0);
        r = min(r, _size(x));

        int sl = _size(x->l);

        if(l >= r)
            return ;

        if (l == 0 && r == _size(x)){
            x->lazy = h(x->lazy, val);
        }
        else{
            if(l <= sl && sl < r)
                x->val = g(x->val, val, 1);

            _add(x->l, l, r, val);
            _add(x->r, l - sl - 1, r - sl - 1, val);
        }

        _update(x);
    }

    np _getnode(np x, int k){

        _update(x);

        assert(0 <= k && k < _size(x));

        if(k < _size(x->l))
            return _getnode(x->l, k);
        else if(_size(x->l) == k)
            return x;
        else
            return _getnode(x->r, k - _size(x->l) - 1);
    }

    T _get(np x, int k){
        return _getnode(x, k)->val;
    }

    T _rangesum(np x, int l, int r){
        _update(x);

        l = max(l, 0);
        r = min(r, _size(x));
        if(l >= r)
            return OT;
        if(l == 0 && r == _size(x))
            return _sum(x);

        int sl = _size(x->l);
        T ret = (l <= sl && sl < r ? x->val : OT);
        ret = f(_rangesum(x->l, l, r), ret);
        ret = f(ret, _rangesum(x->r, l - sl - 1, r - sl - 1));
        return ret;
    }

    int _lowerbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val <= x->val)
            return _lowerbound(x->l, val);
        else
            return _lowerbound(x->r,val) + _size(x->l) + 1;
    }

    int _upperbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val < x->val)
            return _upperbound(x->l, val);
        else
            return _upperbound(x->r,val) + _size(x->l) + 1;
    }

    np _insert(np x, T val){
        return _insert(x, _lowerbound(x, val), val);
    }

    void _clear(np x){
        if(x == nullptr || x == nt::nil)
            return;
        if(x->l != nt::nil){
            _clear(x->l);
            delete(x->l);
            x->l = nt::nil;
        }
        if(x->r != nt::nil){
            _clear(x->r);
            delete(x->r);
            x->r = nt::nil;
        }
    }

    void push_front(T val){
        root = _merge(new nt(val, OU), root);
    }

    void push_back(T val){
        root = _merge(root, new nt(val,OU));
    }

    void pop_front(){
        root = _split(root, 1).second;
    }

    void pop_back(){
        root = _split(root, _size(root) - 1).first;
    }

    // [0, k)と[k, size)に分割して, [k, size)側を返す
    Treap split_left(int k){
        np p;
        tie(root, p) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // [0, k)と[k, size)に分割して, [0, k)側を返す
    Treap split_right(int k){
        np p;
        tie(p, root) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // rootを含めたサイズの出力
    int size(){
        return (root == nt::nil ? 0 : root->size);
    }

    // k番目への代入
    void set(int k, T val){
        return _set(root, k, val);
    }

    // k番目への加算
    void add(int k, U val){
        assert(is_list);
        return _add(root, k, k + 1, val);
    }

    // [l, r)への一様加算
    void add(int l, int r, U val){
        return _add(root, l, r, val);
    }

    // k番目の取得
    T get(int k){
        return _get(root, k);
    }

    // [l, r)の総和 (同様の実装でRMQ等も可能)
    T get(int l, int r){
        return _rangesum(root, l, r);
    }

    // k番目への挿入
    void insert(int k, T val){
        assert(is_list);
        root = _insert(root, k, val);
    }

    // 適切な位置への挿入
    void insert(T val){
        root = _insert(root, val);
    }

    // val <= get(k) となるような最小のk
    int lowerbound(T val){
        return _lowerbound(root, val);
    }

    // val < get(k) となるような最小のk
    int upperbound(T val){
        return _upperbound(root, val);
    }

    // k番目の要素削除
    void erase(int k){
        root = _erase(root, k);
    }

    // 要素の全削除
    void clear(){
        if(root != nullptr && root != nt::nil){
            _clear(root);
            delete(root);
            root = nt::nil;
        }
    }
};

using node_type = Node<i64, pair<i64, bool>>;
template<> node_type* node_type::nil = new node_type(0, make_pair(0, false), 0);


signed main(){
    int n;
    cin >> n;
    vector<int> a(n);
    for(auto& x : a)
        cin >> x;
    int m;
    cin >> m;

    constexpr int packet = 256;
    constexpr int size = (100100) / packet;

    auto f = [&](auto x, auto y){
        if(x.second != y.second)
            return y;
        if(y.second)
            return y;
        return make_pair(x.first + y.first, false);
    };

    vector<Treap<i64, pair<i64, bool>>> tr;
    vector<vector<i64>> elm_idxes(size, vector<i64>(packet));
    for(int i = 0; i < size; ++i){
        int st = packet * i;
        int en = packet * (i + 1);
        vector<i64> e;
        vector<pair<int,int>> v;
        for(int j = st; j < en; ++j){
            e.emplace_back(j < n ? a[j] : 1e9);
            v.emplace_back(e.back(), j - st);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[i][j] = v[j].second;
        auto t = Treap<i64, pair<i64, bool>>::make(e, false, [](auto x, auto y){return x + y;}, 0, [](auto x, auto y, int){return y.second ? 0 : x + y.first;}, f, make_pair(0, false));
        tr.emplace_back(move(t));
    }

    auto get_raw = [&](int idx){
        vector<i64> ret(packet, 0);
        for(int i = 0; i < packet; ++i){
            ret[elm_idxes[idx][i]] = tr[idx].get(i);
        }
        return ret;
    };

    auto rebuild = [&](int idx, std::vector<i64>& elm){
        while(tr[idx].size())
            tr[idx].erase(0);
        vector<pair<int,int>> v;
        for(int j = 0; j < packet; ++j){
            v.emplace_back(elm[j], j);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[idx][j] = v[j].second;
        for(auto& x : elm)
            tr[idx].insert(x);
    };


    for(int _ = 0; _ < m; ++_){
        i64 type, l, r, d;
        cin >> type >> l >> r >> d;
        --l;
        int l_idx = l / packet;
        int r_idx = r / packet;
        int l_mod = l % packet;
        int r_mod = r % packet;
        if(type == 1){
            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i)
                    elm[i] += d;
                rebuild(l_idx, elm);
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i)
                l_elm[i] += d;
            // TODO: rebuild
            rebuild(l_idx, l_elm);
            for(int i = l_idx + 1; i < r_idx; ++i){
                tr[i].add(0, packet, make_pair(d, false));
            }
            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i)
                r_elm[i] += d;
            // TODO: rebuild
            rebuild(r_idx, r_elm);
        }
        else{
            i64 ans = 0;

            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i){
                    ans += min(elm[i], d);
                    elm[i] = max(0LL, elm[i] - d);
                }
                rebuild(l_idx, elm);
                cout << ans << endl;
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i){
                ans += min(l_elm[i], d);
                l_elm[i] = max(0LL, l_elm[i] - d);
            }
            rebuild(l_idx, l_elm);

            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i){
                ans += min(r_elm[i], d);
                r_elm[i] = max(0LL, r_elm[i] - d);
            }
            rebuild(r_idx, r_elm);

            for(int i = l_idx + 1; i < r_idx; ++i){
                int l_bound = tr[i].lowerbound(0);
                int r_bound = tr[i].lowerbound(d);
                ans += tr[i].get(l_bound, r_bound);
                ans += (packet - r_bound) * d;
                tr[i].add(0, r_bound, make_pair(0, true));
                tr[i].add(r_bound, packet, make_pair(-d, false));

            }
            cout << ans << endl;
        }
    }
}
accuracy: 0.2
time_ms: 240
memory_kb: 10348
final_rank: 18

code_snippet: #include "bits/stdc++.h"
using namespace std;
using i64 = long long;
const i64 MOD = 1e9+7;
const i64 INF = 1e18+7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}

template <typename T, typename U = int>
struct Node{

    using np = Node<T, U>*;

    static np nil;

    T val;
    U lazy;
    uint32_t pri;

    int size;
    T sum;

    np l = nil;
    np r = nil;

    Node(T v, U OU = U()) : val(v), lazy(OU), pri(rndpri()), size(1), sum(v), l(nil), r(nil){}
    Node(T v, U OU, uint32_t p) : val(v), lazy(OU), pri(p), size(1), sum(v), l(nil), r(nil){}

    static uint32_t rndpri() {
        static uint32_t x = 123456789, y = 362436069, z = 521288629, w = time(0);
        uint32_t t = x ^ (x << 11);
        x = y;
        y = z;
        z = w;
        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
        return max<uint32_t>(1, w & 0x3FFFFFFF);
    }
};


template <typename T, typename U = int>
class Treap{

    using nt = Node<T, U>;
    using np = nt*;
    using F = function<T(T, T)>;
    using G = function<T(T, U, int)>;
    using H = function<U(U, U)>;

public:

    np root;
    bool is_list;
    F f;
    G g;
    H h;
    T OT;
    U OU;

    Treap(bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    Treap(T val, bool is_list, F f, G g, H h, T OT, U OU) : root(new nt(val)), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    // 配列で初期化する
    Treap(vector<T> v, bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){
        sort(v.begin(), v.end());
        for(auto& x : v)
            push_back(x);
    }

    static Treap make(bool is_list, F f = [](T x, T){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(is_list, f, g, h, OT, OU);
    }

    static Treap make(T val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    static Treap make(vector<T>& val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    ~Treap(){
        /*
        clear();
        if(root != nt::nil)
            delete root;
        */
    }

    int _size(np x){return x == nt::nil ? 0 : x->size;}
    T _sum(np x){return x == nt::nil ? OT : x->sum;}

    np _update(np x){

        if(x == nt::nil)
            return x;

        if(is_list){
            _push(x);
            _push(x->l);
            _push(x->r);
        }

  x->sum = f(f(_sum(x->l), x->val), _sum(x->r));
  x->size = _size(x->l) + _size(x->r) + 1;
        return x;
    }

    void _push(np x){
        if(x->lazy == OU)
            return ;

        x->sum = g(x->sum, x->lazy, x->size);
        x->val = g(x->val, x->lazy, 1);

        if(x->l != nt::nil)
            x->l->lazy = h(x->l->lazy, x->lazy);
        if(x->r != nt::nil)
            x->r->lazy = h(x->r->lazy, x->lazy);

        x->lazy = OU;

    }

    np _merge(np l, np r){
        if(l == nt::nil || r ==nt::nil)
            return l == nt::nil ? r : l;

        if(l->pri > r->pri){
            l->r = _merge(l->r, r);
            return _update(l);
        }else{
            r->l = _merge(l, r->l);
            return _update(r);
        }
    }

    pair<np,np> _split(np x, int k){
        if(x == nt::nil)
            return make_pair(nt::nil, nt::nil);

        assert(0 <= k && k <= _size(x));

        if(k <= _size(x->l)){
            pair<np, np> s = _split(x->l, k);
            x->l = s.second;
            return make_pair(s.first, _update(x));

        }else{
            pair<np, np> s = _split(x->r, k - _size(x->l) - 1);
            x->r = s.first;
            return make_pair(_update(x), s.second);
        }
    }

    np _insert(np x, int k, T val){
        np l, r;
        tie(l, r) = _split(x, k);
        return _merge(_merge(l, new nt(val, OU)), r);
    }

    np _erase(np x, int k){
        np l, r, m;
        tie(l, r) = _split(x, k);
        tie(m, r) = _split(r, 1);
        if(m != nt::nil)
            delete m;
        return _merge(l, r);
    }

    void _set(np x, int k, T val){
        _update(x);

        if(k < _size(x->l))
            _set(x->l, k, val);
        else if(_size(x->l) == k)
            x->val = val;
        else
            _set(x->r, k - _size(x->l) - 1, val);

        _update(x);
    }

    void _add(np x, int l, int r, U val){
        _update(x);

        if(x == nt::nil)
            return ;
        l = max(l, 0);
        r = min(r, _size(x));

        int sl = _size(x->l);

        if(l >= r)
            return ;

        if (l == 0 && r == _size(x)){
            x->lazy = h(x->lazy, val);
        }
        else{
            if(l <= sl && sl < r)
                x->val = g(x->val, val, 1);

            _add(x->l, l, r, val);
            _add(x->r, l - sl - 1, r - sl - 1, val);
        }

        _update(x);
    }

    np _getnode(np x, int k){

        _update(x);

        assert(0 <= k && k < _size(x));

        if(k < _size(x->l))
            return _getnode(x->l, k);
        else if(_size(x->l) == k)
            return x;
        else
            return _getnode(x->r, k - _size(x->l) - 1);
    }

    T _get(np x, int k){
        return _getnode(x, k)->val;
    }

    T _rangesum(np x, int l, int r){
        _update(x);

        l = max(l, 0);
        r = min(r, _size(x));
        if(l >= r)
            return OT;
        if(l == 0 && r == _size(x))
            return _sum(x);

        int sl = _size(x->l);
        T ret = (l <= sl && sl < r ? x->val : OT);
        ret = f(_rangesum(x->l, l, r), ret);
        ret = f(ret, _rangesum(x->r, l - sl - 1, r - sl - 1));
        return ret;
    }

    int _lowerbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val <= x->val)
            return _lowerbound(x->l, val);
        else
            return _lowerbound(x->r,val) + _size(x->l) + 1;
    }

    int _upperbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val < x->val)
            return _upperbound(x->l, val);
        else
            return _upperbound(x->r,val) + _size(x->l) + 1;
    }

    np _insert(np x, T val){
        return _insert(x, _lowerbound(x, val), val);
    }

    void _clear(np x){
        if(x == nullptr || x == nt::nil)
            return;
        if(x->l != nt::nil){
            _clear(x->l);
            delete(x->l);
            x->l = nt::nil;
        }
        if(x->r != nt::nil){
            _clear(x->r);
            delete(x->r);
            x->r = nt::nil;
        }
    }

    void push_front(T val){
        root = _merge(new nt(val, OU), root);
    }

    void push_back(T val){
        root = _merge(root, new nt(val,OU));
    }

    void pop_front(){
        root = _split(root, 1).second;
    }

    void pop_back(){
        root = _split(root, _size(root) - 1).first;
    }

    // [0, k)と[k, size)に分割して, [k, size)側を返す
    Treap split_left(int k){
        np p;
        tie(root, p) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // [0, k)と[k, size)に分割して, [0, k)側を返す
    Treap split_right(int k){
        np p;
        tie(p, root) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // rootを含めたサイズの出力
    int size(){
        return (root == nt::nil ? 0 : root->size);
    }

    // k番目への代入
    void set(int k, T val){
        return _set(root, k, val);
    }

    // k番目への加算
    void add(int k, U val){
        assert(is_list);
        return _add(root, k, k + 1, val);
    }

    // [l, r)への一様加算
    void add(int l, int r, U val){
        return _add(root, l, r, val);
    }

    // k番目の取得
    T get(int k){
        return _get(root, k);
    }

    // [l, r)の総和 (同様の実装でRMQ等も可能)
    T get(int l, int r){
        return _rangesum(root, l, r);
    }

    // k番目への挿入
    void insert(int k, T val){
        assert(is_list);
        root = _insert(root, k, val);
    }

    // 適切な位置への挿入
    void insert(T val){
        root = _insert(root, val);
    }

    // val <= get(k) となるような最小のk
    int lowerbound(T val){
        return _lowerbound(root, val);
    }

    // val < get(k) となるような最小のk
    int upperbound(T val){
        return _upperbound(root, val);
    }

    // k番目の要素削除
    void erase(int k){
        root = _erase(root, k);
    }

    // 要素の全削除
    void clear(){
        if(root != nullptr && root != nt::nil){
            _clear(root);
            delete(root);
            root = nt::nil;
        }
    }
};

using node_type = Node<i64, pair<i64, bool>>;
template<> node_type* node_type::nil = new node_type(0, make_pair(0, false), 0);


signed main(){
    int n;
    cin >> n;
    vector<int> a(n);
    for(auto& x : a)
        cin >> x;
    int m;
    cin >> m;

    constexpr int packet = 2;
    constexpr int size = (100100) / packet;

    auto f = [&](auto x, auto y){
        if(x.second != y.second)
            return y;
        if(y.second)
            return y;
        return make_pair(x.first + y.first, false);
    };

    vector<Treap<i64, pair<i64, bool>>> tr;
    vector<vector<i64>> elm_idxes(size, vector<i64>(packet));
    for(int i = 0; i < size; ++i){
        int st = packet * i;
        int en = packet * (i + 1);
        vector<i64> e;
        vector<pair<int,int>> v;
        for(int j = st; j < en; ++j){
            e.emplace_back(j < n ? a[j] : 1e9);
            v.emplace_back(e.back(), j - st);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[i][j] = v[j].second;
        auto t = Treap<i64, pair<i64, bool>>::make(e, false, [](auto x, auto y){return x + y;}, 0, [](auto x, auto y, int){return y.second ? 0 : x + y.first;}, f, make_pair(0, false));
        tr.emplace_back(move(t));
    }

    auto get_raw = [&](int idx){
        vector<i64> ret(packet, 0);
        for(int i = 0; i < packet; ++i){
            ret[elm_idxes[idx][i]] = tr[idx].get(i);
        }
        return ret;
    };

    auto rebuild = [&](int idx, std::vector<i64>& elm){
        while(tr[idx].size())
            tr[idx].erase(0);
        vector<pair<int,int>> v;
        for(int j = 0; j < packet; ++j){
            v.emplace_back(elm[j], j);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[idx][j] = v[j].second;
        for(auto& x : elm)
            tr[idx].insert(x);
    };


    for(int _ = 0; _ < m; ++_){
        i64 type, l, r, d;
        cin >> type >> l >> r >> d;
        --l;
        int l_idx = l / packet;
        int r_idx = r / packet;
        int l_mod = l % packet;
        int r_mod = r % packet;
        if(type == 1){
            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i)
                    elm[i] += d;
                rebuild(l_idx, elm);
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i)
                l_elm[i] += d;
            // TODO: rebuild
            rebuild(l_idx, l_elm);
            for(int i = l_idx + 1; i < r_idx; ++i){
                tr[i].add(0, packet, make_pair(d, false));
            }
            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i)
                r_elm[i] += d;
            // TODO: rebuild
            rebuild(r_idx, r_elm);
        }
        else{
            i64 ans = 0;

            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i){
                    ans += min(elm[i], d);
                    elm[i] = max(0LL, elm[i] - d);
                }
                rebuild(l_idx, elm);
                cout << ans << endl;
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i){
                ans += min(l_elm[i], d);
                l_elm[i] = max(0LL, l_elm[i] - d);
            }
            rebuild(l_idx, l_elm);

            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i){
                ans += min(r_elm[i], d);
                r_elm[i] = max(0LL, r_elm[i] - d);
            }
            rebuild(r_idx, r_elm);

            for(int i = l_idx + 1; i < r_idx; ++i){
                int l_bound = tr[i].lowerbound(0);
                int r_bound = tr[i].lowerbound(d);
                ans += tr[i].get(l_bound, r_bound);
                ans += (packet - r_bound) * d;
                tr[i].add(0, r_bound, make_pair(0, true));
                tr[i].add(r_bound, packet, make_pair(-d, false));

            }
            cout << ans << endl;
        }
    }
}
accuracy: 0.05
time_ms: 10
memory_kb: 18428
final_rank: 20

code_snippet: #include "bits/stdc++.h"
using namespace std;
using i64 = long long;
const i64 MOD = 1e9+7;
const i64 INF = 1e18+7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}

template <typename T, typename U = int>
struct Node{

    using np = Node<T, U>*;

    static np nil;

    T val;
    U lazy;
    uint32_t pri;

    int size;
    T sum;

    np l = nil;
    np r = nil;

    Node(T v, U OU = U()) : val(v), lazy(OU), pri(rndpri()), size(1), sum(v), l(nil), r(nil){}
    Node(T v, U OU, uint32_t p) : val(v), lazy(OU), pri(p), size(1), sum(v), l(nil), r(nil){}

    static uint32_t rndpri() {
        static uint32_t x = 123456789, y = 362436069, z = 521288629, w = time(0);
        uint32_t t = x ^ (x << 11);
        x = y;
        y = z;
        z = w;
        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
        return max<uint32_t>(1, w & 0x3FFFFFFF);
    }
};


template <typename T, typename U = int>
class Treap{

    using nt = Node<T, U>;
    using np = nt*;
    using F = function<T(T, T)>;
    using G = function<T(T, U, int)>;
    using H = function<U(U, U)>;

public:

    np root;
    bool is_list;
    F f;
    G g;
    H h;
    T OT;
    U OU;

    Treap(bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    Treap(T val, bool is_list, F f, G g, H h, T OT, U OU) : root(new nt(val)), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){}

    // 配列で初期化する
    Treap(vector<T> v, bool is_list, F f, G g, H h, T OT, U OU) : root(nt::nil), is_list(is_list), f(f), g(g), h(h), OT(OT), OU(OU){
        sort(v.begin(), v.end());
        for(auto& x : v)
            push_back(x);
    }

    static Treap make(bool is_list, F f = [](T x, T){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(is_list, f, g, h, OT, OU);
    }

    static Treap make(T val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    static Treap make(vector<T>& val, bool is_list, F f = [](auto x, auto){return x;}, T OT = T(), G g = [](auto x, auto, auto){return x;}, H h = [](auto x, auto){return x;}, U OU = U()){
        assert(nt::nil != nullptr);
        return Treap(val, is_list, f, g, h, OT, OU);
    }

    ~Treap(){
        /*
        clear();
        if(root != nt::nil)
            delete root;
        */
    }

    int _size(np x){return x == nt::nil ? 0 : x->size;}
    T _sum(np x){return x == nt::nil ? OT : x->sum;}

    np _update(np x){

        if(x == nt::nil)
            return x;

        if(is_list){
            _push(x);
            _push(x->l);
            _push(x->r);
        }

  x->sum = f(f(_sum(x->l), x->val), _sum(x->r));
  x->size = _size(x->l) + _size(x->r) + 1;
        return x;
    }

    void _push(np x){
        if(x->lazy == OU)
            return ;

        x->sum = g(x->sum, x->lazy, x->size);
        x->val = g(x->val, x->lazy, 1);

        if(x->l != nt::nil)
            x->l->lazy = h(x->l->lazy, x->lazy);
        if(x->r != nt::nil)
            x->r->lazy = h(x->r->lazy, x->lazy);

        x->lazy = OU;

    }

    np _merge(np l, np r){
        if(l == nt::nil || r ==nt::nil)
            return l == nt::nil ? r : l;

        if(l->pri > r->pri){
            l->r = _merge(l->r, r);
            return _update(l);
        }else{
            r->l = _merge(l, r->l);
            return _update(r);
        }
    }

    pair<np,np> _split(np x, int k){
        if(x == nt::nil)
            return make_pair(nt::nil, nt::nil);

        assert(0 <= k && k <= _size(x));

        if(k <= _size(x->l)){
            pair<np, np> s = _split(x->l, k);
            x->l = s.second;
            return make_pair(s.first, _update(x));

        }else{
            pair<np, np> s = _split(x->r, k - _size(x->l) - 1);
            x->r = s.first;
            return make_pair(_update(x), s.second);
        }
    }

    np _insert(np x, int k, T val){
        np l, r;
        tie(l, r) = _split(x, k);
        return _merge(_merge(l, new nt(val, OU)), r);
    }

    np _erase(np x, int k){
        np l, r, m;
        tie(l, r) = _split(x, k);
        tie(m, r) = _split(r, 1);
        if(m != nt::nil)
            delete m;
        return _merge(l, r);
    }

    void _set(np x, int k, T val){
        _update(x);

        if(k < _size(x->l))
            _set(x->l, k, val);
        else if(_size(x->l) == k)
            x->val = val;
        else
            _set(x->r, k - _size(x->l) - 1, val);

        _update(x);
    }

    void _add(np x, int l, int r, U val){
        _update(x);

        if(x == nt::nil)
            return ;
        l = max(l, 0);
        r = min(r, _size(x));

        int sl = _size(x->l);

        if(l >= r)
            return ;

        if (l == 0 && r == _size(x)){
            x->lazy = h(x->lazy, val);
        }
        else{
            if(l <= sl && sl < r)
                x->val = g(x->val, val, 1);

            _add(x->l, l, r, val);
            _add(x->r, l - sl - 1, r - sl - 1, val);
        }

        _update(x);
    }

    np _getnode(np x, int k){

        _update(x);

        assert(0 <= k && k < _size(x));

        if(k < _size(x->l))
            return _getnode(x->l, k);
        else if(_size(x->l) == k)
            return x;
        else
            return _getnode(x->r, k - _size(x->l) - 1);
    }

    T _get(np x, int k){
        return _getnode(x, k)->val;
    }

    T _rangesum(np x, int l, int r){
        _update(x);

        l = max(l, 0);
        r = min(r, _size(x));
        if(l >= r)
            return OT;
        if(l == 0 && r == _size(x))
            return _sum(x);

        int sl = _size(x->l);
        T ret = (l <= sl && sl < r ? x->val : OT);
        ret = f(_rangesum(x->l, l, r), ret);
        ret = f(ret, _rangesum(x->r, l - sl - 1, r - sl - 1));
        return ret;
    }

    int _lowerbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val <= x->val)
            return _lowerbound(x->l, val);
        else
            return _lowerbound(x->r,val) + _size(x->l) + 1;
    }

    int _upperbound(np x, T val){
        _update(x);

        if(x == nt::nil)
            return 0;
        if(val < x->val)
            return _upperbound(x->l, val);
        else
            return _upperbound(x->r,val) + _size(x->l) + 1;
    }

    np _insert(np x, T val){
        return _insert(x, _lowerbound(x, val), val);
    }

    void _clear(np x){
        if(x == nullptr || x == nt::nil)
            return;
        if(x->l != nt::nil){
            _clear(x->l);
            delete(x->l);
            x->l = nt::nil;
        }
        if(x->r != nt::nil){
            _clear(x->r);
            delete(x->r);
            x->r = nt::nil;
        }
    }

    void push_front(T val){
        root = _merge(new nt(val, OU), root);
    }

    void push_back(T val){
        root = _merge(root, new nt(val,OU));
    }

    void pop_front(){
        root = _split(root, 1).second;
    }

    void pop_back(){
        root = _split(root, _size(root) - 1).first;
    }

    // [0, k)と[k, size)に分割して, [k, size)側を返す
    Treap split_left(int k){
        np p;
        tie(root, p) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // [0, k)と[k, size)に分割して, [0, k)側を返す
    Treap split_right(int k){
        np p;
        tie(p, root) = _split(root, k);
        return decltype(this)(f, g, h, p);
    }

    // rootを含めたサイズの出力
    int size(){
        return (root == nt::nil ? 0 : root->size);
    }

    // k番目への代入
    void set(int k, T val){
        return _set(root, k, val);
    }

    // k番目への加算
    void add(int k, U val){
        assert(is_list);
        return _add(root, k, k + 1, val);
    }

    // [l, r)への一様加算
    void add(int l, int r, U val){
        return _add(root, l, r, val);
    }

    // k番目の取得
    T get(int k){
        return _get(root, k);
    }

    // [l, r)の総和 (同様の実装でRMQ等も可能)
    T get(int l, int r){
        return _rangesum(root, l, r);
    }

    // k番目への挿入
    void insert(int k, T val){
        assert(is_list);
        root = _insert(root, k, val);
    }

    // 適切な位置への挿入
    void insert(T val){
        root = _insert(root, val);
    }

    // val <= get(k) となるような最小のk
    int lowerbound(T val){
        return _lowerbound(root, val);
    }

    // val < get(k) となるような最小のk
    int upperbound(T val){
        return _upperbound(root, val);
    }

    // k番目の要素削除
    void erase(int k){
        root = _erase(root, k);
    }

    // 要素の全削除
    void clear(){
        if(root != nullptr && root != nt::nil){
            _clear(root);
            delete(root);
            root = nt::nil;
        }
    }
};

using node_type = Node<i64, pair<i64, bool>>;
template<> node_type* node_type::nil = new node_type(0, make_pair(0, false), 0);


signed main(){
    int n;
    cin >> n;
    vector<int> a(n);
    for(auto& x : a)
        cin >> x;
    int m;
    cin >> m;

    constexpr int packet = 512;
    constexpr int size = (100000 + packet - 1) / 512;

    vector<Treap<i64, pair<i64, bool>>> tr;
    vector<vector<i64>> elm_idxes(size, vector<i64>(packet));
    for(int i = 0; i < size; ++i){
        int st = packet * i;
        int en = packet * (i + 1);
        vector<i64> e;
        vector<pair<int,int>> v;
        for(int j = st; j < en; ++j){
            e.emplace_back(j < n ? a[j] : 0);
            v.emplace_back(e.back(), j);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[i][j] = v[j].second;
        auto t = Treap<i64, pair<i64, bool>>::make(e, false, [](auto x, auto y){return x + y;}, 0, [](auto x, auto y, int){return y.second ? 0 : x + y.first;}, [](auto x, auto y){return make_pair(x.first + y.first, x.second | y.second);}, make_pair(0, false));
        tr.emplace_back(move(t));
    }

    auto get_raw = [&](int idx){
        vector<i64> ret(packet, 0);
        for(int i = 0; i < packet; ++i){
            ret[elm_idxes[idx][i]] = tr[idx].get(i);
        }
        return ret;
    };

    auto rebuild = [&](int idx, std::vector<i64>& elm){
        while(tr[idx].size())
            tr[idx].erase(0);
        vector<pair<int,int>> v;
        for(int j = 0; j < packet; ++j){
            v.emplace_back(elm[j], j);
        }
        sort(v.begin(), v.end());
        for(int j = 0; j < packet; ++j)
            elm_idxes[idx][j] = v[j].second;
        for(auto& x : elm)
            tr[idx].insert(x);
    };

    for(int _ = 0; _ < m; ++_){
        i64 type, l, r, d;
        cin >> type >> l >> r >> d;
        --l;
        int l_idx = l / packet;
        int r_idx = r / packet;
        int l_mod = l % packet;
        int r_mod = r % packet;
        if(type == 1){
            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i)
                    elm[i] += d;
                rebuild(l_idx, elm);
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i)
                l_elm[i] += d;
            // TODO: rebuild
            rebuild(l_idx, l_elm);
            for(int i = l_idx; i < r_idx; ++i){
                tr[i].add(0, packet, make_pair(d, false));
            }
            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i)
                r_elm[i] += d;
            // TODO: rebuild
            rebuild(r_idx, r_elm);
        }
        else{
            i64 ans = 0;

            if(l_idx == r_idx){
                auto elm = get_raw(l_idx);
                for(int i = l_mod; i < r_mod; ++i){
                    ans += min(elm[i], d);
                    elm[i] = max(0LL, elm[i] - d);
                }
                rebuild(l_idx, elm);
                cout << ans << endl;
                continue;
            }

            auto l_elm = get_raw(l_idx);
            for(int i = l_mod; i < packet; ++i){
                ans += min(l_elm[i], d);
                l_elm[i] = max(0LL, l_elm[i] - d);
            }
            rebuild(l_idx, l_elm);

            auto r_elm = get_raw(r_idx);
            for(int i = 0; i < r_mod; ++i){
                ans += min(r_elm[i], d);
                r_elm[i] = max(0LL, r_elm[i] - d);
            }
            rebuild(r_idx, r_elm);

            for(int i = l_idx; i < r_idx; ++i){
                int l_bound = tr[i].lowerbound(0);
                int r_bound = tr[i].lowerbound(d);
                ans += tr[i].get(l_bound, r_bound);
                ans += (packet - r_bound) * d;
                tr[i].add(0, packet, make_pair(0, true));
            }
            cout << ans << endl;
        }
    }
}
accuracy: 0.2
time_ms: 20
memory_kb: 10336
final_rank: 17