#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10; #define ls (rt<<1) #define rs (rt<<1|1) #define mid (l+r>>1) typedef long long ll; struct Node{ ll sum; int ma, se; int t; int lazy; int lazy1; }node[maxn<<2]; int n, q; int a[maxn]; void push_up(int rt){ if(node[ls].ma == node[rs].ma){ node[rt].t = node[ls].t + node[rs].t; node[rt].ma = node[ls].ma; node[rt].se = max(node[ls].se, node[rs].se); } else if(node[ls].ma>node[rs].ma){ node[rt].t = node[ls].t; node[rt].ma = node[ls].ma; node[rt].se = max(node[ls].se, node[rs].ma); } else{ node[rt].t = node[rs].t; node[rt].ma = node[rs].ma; node[rt].se = max(node[rs].se, node[ls].ma); } node[rt].sum = node[ls].sum + node[rs].sum; return; } void build(int rt, int l, int r){ node[rt].lazy = node[rt].lazy1 = 0, node[rt].se = -1e9; if(l == r){ node[rt].ma = a[l]; node[rt].sum = a[l]; node[rt].t = 1; return; } build(ls, l, mid); build(rs, mid+1, r); push_up(rt); } void push_down(int rt, int l, int r){ if(!(l < r)) return ; int val = node[rt].ma; int len1 = (mid-l+1); int len2 = r-mid; if(node[rt].lazy1){ node[ls].sum += (node[rt].lazy1)*len1; node[rs].sum += node[rt].lazy1*len2; node[ls].se += node[rt].lazy1; node[rs].se += node[rt].lazy1; node[ls].ma += node[rt].lazy1; node[rs].ma += node[rt].lazy1; node[ls].lazy1 += node[rt].lazy1; node[rs].lazy1 += node[rt].lazy1; } if (node[rt].lazy&&node[ls].se< val && node[ls].ma>val) { node[ls].sum -= (1ll)*node[ls].t*(node[ls].ma-val); node[ls].ma = val; node[ls].lazy = 1; } if (node[rt].lazy&&node[rs].se< val && node[rs].ma>val) { node[rs].sum -= (1ll)*node[rs].t*(node[rs].ma-val); node[rs].ma = val; node[rs].lazy = 1; } node[rt].lazy1 = 0; node[rt].lazy = 0; } void update(int rt, int l, int r, int ql, int qr, int val){ if(ql<=l&&qr>=r){ if(node[rt].lazy1) push_down(rt, l, r); if(val>=node[rt].ma) return ; if(val>node[rt].se){ node[rt].sum -= (1ll)*(node[rt].ma-val)*node[rt].t; node[rt].lazy = 1; node[rt].ma = val; return; } } if(node[rt].lazy||node[rt].lazy1) push_down(rt, l, r); if(qr<=mid) update(ls, l, mid, ql ,qr, val); else if(ql>mid) update(rs, mid+1, r, ql ,qr, val); else update(ls, l, mid, ql, qr, val), update(rs, mid+1, r, ql ,qr, val); push_up(rt); } ll query_mx(int rt, int l ,int r, int ql ,int qr){ if(ql<=l&&qr>=r){ return (ll)node[rt].ma; } if(node[rt].lazy||node[rt].lazy1) push_down(rt, l, r); ll ans; if(qr <= mid){ ans = query_mx(ls, l, mid, ql ,qr); } else if(ql > mid){ ans = query_mx(rs, mid+1, r, ql ,qr); } else { ans = max(query_mx(ls, l, mid, ql, qr), query_mx(rs, mid+1, r, ql ,qr)); } push_up(rt); return ans; } ll query_sum(int rt, int l, int r, int ql, int qr){ if(ql<=l && qr>=r) return node[rt].sum; if(node[rt].lazy||node[rt].lazy1) push_down(rt, l, r); if(qr<=mid) return query_sum(ls, l, mid, ql ,qr); else if(ql>mid) return query_sum(rs, mid+1, r, ql ,qr); else return query_sum(ls, l, mid, ql ,qr)+ query_sum(rs, mid+1, r, ql ,qr); } void add(int rt, int l, int r, int ql, int qr, int val){ if(ql<=l&&qr>=r){ node[rt].lazy1 += val; node[rt].ma += val; node[rt].sum += (r-l+1)*val; node[rt].se += val; return; } if(node[rt].lazy||node[rt].lazy1) push_down(rt, l, r); if(qr<=mid) add(ls, l, mid, ql ,qr, val); else if(ql>mid) add(rs, mid+1, r, ql ,qr, val); else add(ls, l, mid, ql ,qr, val), add(rs, mid+1, r, ql, qr, val); push_up(rt); } int main(){ scanf("%d", &n); assert(1 <= n && n <= 100000); for(int i=1; i<=n; i++){ scanf("%d", &a[i]); } build(1, 1, n); int op, l, r, val; scanf("%d", &q); for(int i=1; i<=q; i++){ scanf("%d", &op); if(op == 1){ scanf("%d%d%d", &l, &r, &val); assert(l <= r && 1 <= l && l <= n && 1 <= r && r <= n); update(1, 1, n, l, r, val); } else if(op == 3){ scanf("%d%d", &l,&r); assert(l <= r && 1 <= l && l <= n && 1 <= r && r <= n); printf("%lld\n", query_sum(1, 1, n, l, r)); } else { scanf("%d%d%d", &l, &r, &val); assert(l <= r && 1 <= l && l <= n && 1 <= r && r <= n); add(1, 1, n, l, r, val); } } return 0; }
|