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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include<cstdio> #include<algorithm> #include<ctype.h> #include<string.h> #include<math.h>
using namespace std; #define ll long long
inline char read() { static const int IN_LEN = 1000000; static char buf[IN_LEN], *s, *t; return (s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin), (s == t ? -1 : *s++) : *s++); } template<class T> inline void read(T &x) { static bool iosig; static char c; for (iosig = false, c = read(); !isdigit(c); c = read()) { if (c == '-') iosig = true; if (c == -1) return; } for (x = 0; isdigit(c); c = read()) x = ((x + (x << 2)) << 1) + (c ^ '0'); if (iosig) x = -x; } const int OUT_LEN = 10000000; char obuf[OUT_LEN], *ooh = obuf; inline void print(char c) { if (ooh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), ooh = obuf; *ooh++ = c; } template<class T> inline void print(T x) { static int buf[30], cnt; if (x == 0) print('0'); else { if (x < 0) print('-'), x = -x; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; while (cnt) print((char)buf[cnt--]); } } inline void flush() { fwrite(obuf, 1, ooh - obuf, stdout); } const int N = 1000005; int T, n, m, a[N], mx[N<<2], se[N<<2], cnt[N<<2]; ll s[N<<2]; inline void update(int t){ int k=t<<1; if(mx[k]<mx[k|1]) mx[t]=mx[k|1], cnt[t]=cnt[k|1], se[t]=max(mx[k], se[k|1]); else if(mx[k]>mx[k|1]) mx[t]=mx[k], cnt[t]=cnt[k], se[t]=max(mx[k|1], se[k]); else mx[t]=mx[k], cnt[t]=cnt[k]+cnt[k|1], se[t]=max(se[k], se[k|1]); s[t]=s[k]+s[k|1]; } void pushdown(int t){ int k=t<<1; if(mx[t]<mx[k]) s[k]-=(ll)(mx[k]-mx[t])*cnt[k], mx[k]=mx[t]; if(mx[t]<mx[k|1]) s[k|1]-=(ll)(mx[k|1]-mx[t])*cnt[k|1], mx[k|1]=mx[t]; } void build(int l, int r, int t){ if(l==r) return (void)(mx[t]=s[t]=a[l], cnt[t]=1, se[t]=-1); int mid=l+r>>1, k=t<<1; build(l, mid, k), build(mid+1, r, k|1); update(t); } void change(int l, int r, int t, int L, int R, int x){ if(x>=mx[t]) return; if(L<=l && r<=R && x>se[t]) return (void)(s[t]-=(ll)(mx[t]-x)*cnt[t], mx[t]=x); int mid=l+r>>1, k=t<<1; pushdown(t); if(L<=mid) change(l, mid, k, L, R, x); if(R>mid) change(mid+1, r, k|1, L, R, x); update(t); } int query1(int l, int r, int t, int L, int R){ if(L<=l && r<=R) return mx[t]; int mid=l+r>>1, k=t<<1; pushdown(t); if(R<=mid) return query1(l, mid, k, L, R); if(L>mid) return query1(mid+1, r, k|1, L, R); return max(query1(l, mid, k, L, R), query1(mid+1, r, k|1, L, R)); } ll query2(int l, int r, int t, int L, int R){ if(L<=l && r<=R) return s[t]; int mid=l+r>>1, k=t<<1; pushdown(t); return (L<=mid?query2(l, mid, k, L, R):0)+(R>mid?query2(mid+1, r, k|1, L, R):0); } int main() { read(T); while(T--){ read(n), read(m); for(int i=1; i<=n; ++i) read(a[i]); build(1, n, 1); while(m--){ static int opt, l, r, t; read(opt), read(l), read(r); if(!opt) read(t), change(1, n, 1, l, r, t); else if(opt==1) print(query1(1, n, 1, l, r)), print('\n'); else print(query2(1, n, 1, l, r)), print('\n'); } } return flush(), 0; }
|