1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <bits/stdc++.h> #define MAX_N 300000 #define INF (1LL<<50) #define mid ((s+t)>>1) using namespace std; typedef long long lnt; template <class T> inline void read(T &x) { x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, m; struct Tag {lnt x, c;} tag[MAX_N<<2]; struct Node {lnt mi1, mi2; int cnt, tot;} tr[MAX_N<<2]; Node operator + (Node a, Node b) { Node ret = (Node){0, 0, 0, a.tot+b.tot}; if (a.mi1 == b.mi1) ret.mi1 = a.mi1, ret.cnt = a.cnt+b.cnt, ret.mi2 = min(a.mi2, b.mi2); else if (a.mi1 < b.mi1) ret.mi1 = a.mi1, ret.cnt = a.cnt, ret.mi2 = min(a.mi2, b.mi1); else ret.mi1 = b.mi1, ret.cnt = b.cnt, ret.mi2 = min(a.mi1, b.mi2); return ret; } Tag operator + (Tag a, Tag b) {return (Tag){max(a.x+b.x, -INF), max(a.c+b.x, b.c)};} void build(int v, int s, int t) { tag[v] = (Tag){0, -INF}; if (s == t) {read(tr[v].mi1), tr[v].mi2 = INF, tr[v].cnt = 1, tr[v].tot = 0; return;} build(v<<1, s, mid), build(v<<1|1, mid+1, t), tr[v] = tr[v<<1]+tr[v<<1|1]; } void maintain(int v, Tag tg) ; void downtag(int v) { tag[v<<1] = tag[v<<1]+tag[v], tag[v<<1|1] = tag[v<<1|1]+tag[v]; maintain(v<<1, tag[v]), maintain(v<<1|1, tag[v]), tag[v] = (Tag){0, -INF}; } void maintain(int v, Tag tg) { lnt tmi1 = max(max(tr[v].mi1+tg.x, tg.c), 0LL); lnt tmi2 = max(max(tr[v].mi2+tg.x, tg.c), 0LL); tmi1 = min(tmi1, INF), tmi2 = min(tmi2, INF); if (tr[v].mi2 == INF) tmi2 = INF; if (tmi1 < tmi2) tr[v].mi1 = tmi1, tr[v].mi2 = tmi2, tr[v].tot = tmi1 ? 0 : tr[v].cnt; else downtag(v), tr[v] = tr[v<<1]+tr[v<<1|1]; } void modify(int v, int s, int t, int l, int r, Tag tg) { if (s >= l && t <= r) {tag[v] = tag[v]+tg, maintain(v, tg); return;} downtag(v); if (l <= mid) modify(v<<1, s, mid, l, r, tg); if (r >= mid+1) modify(v<<1|1, mid+1, t, l, r, tg); tr[v] = tr[v<<1]+tr[v<<1|1]; } int query(int v, int s, int t, int l, int r) { if (s >= l && t <= r) return tr[v].tot; int ret = 0; downtag(v); if (l <= mid) ret += query(v<<1, s, mid, l, r); if (r >= mid+1) ret += query(v<<1|1, mid+1, t, l, r); tr[v] = tr[v<<1]+tr[v<<1|1]; return ret; } int main() { read(n), read(m), build(1, 1, n); while (m--) { int opt, l, r, x; read(opt), read(l), read(r); if (opt == 1) read(x), modify(1, 1, n, l, r, (Tag){-INF, x}); if (opt == 2) read(x), modify(1, 1, n, l, r, (Tag){x, 0}); if (opt == 3) printf("%d\n", query(1, 1, n, l, r)); } return 0; }
|