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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include<bits/stdc++.h> #define inf 0x3f3f3f3f3f3f3f3f #define ll long long #define N 400005 using namespace std; inline char nc(){ static char buf[1000000],*p=buf,*q=buf; return p==q&&(q=(p=buf)+fread(buf,1,1000000,stdin),p==q)?EOF:*p++; } inline ll read(){ ll res = 0,w = 1; char c = nc(); while(c<'0'||c>'9'){ if(c=='-') w=-1; c=nc(); } while(c<='9'&&c>='0')res=res*10+c-'0',c=nc(); return res*w; } char obuf[1<<21],*p3=obuf; inline void pc(char c){ p3-obuf<=(1<<20)?(*p3++=c):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=c); } inline void write(long long x){ if(x<0) pc('-'),x=-x; if(x>9) write(x/10); pc(x%10+'0'); } struct poly{ long long k,b; inline void add(long long x){b+=k*x;} }; inline poly operator+(const poly a,const poly b){return (poly){a.k+b.k,a.b+b.b};} inline poly max(poly a,poly b){ if(a.k<b.k||(a.k==b.k&&a.b<b.b)) swap(a,b); if(a.b>=b.b) return a; return b; } inline long long get(poly a,poly b){ if(a.k==b.k) return inf; if(a.k<b.k) swap(a,b); if(b.b<a.b) return inf; return (b.b-a.b)/(a.k-b.k); } struct node{ poly smax,lmax,rmax,sum; long long s,tag,minn,sminn; }tr[N<<2],c; inline node merge(node a,node b){ c.minn = min(a.minn,b.minn); if(c.minn==a.minn&&c.minn==b.minn) c.sminn=min(a.sminn,b.sminn); else if(c.minn==a.minn) c.sminn=min(a.sminn,b.minn); else c.sminn=min(a.minn,b.sminn); if(c.minn!=a.minn) a.sum.k=a.lmax.k=a.rmax.k=a.smax.k=0; if(c.minn!=b.minn) b.sum.k=b.lmax.k=b.rmax.k=b.smax.k=0; c.sum = a.sum + b.sum; c.smax = max(a.smax,max(b.smax,a.rmax+b.lmax)); c.lmax = max(a.lmax,b.lmax+a.sum); c.rmax = max(b.rmax,a.rmax+b.sum); c.s = min({a.s,b.s,get(a.lmax,b.lmax+a.sum),get(b.rmax,a.rmax+b.sum),get(a.smax,b.smax),get(b.smax,a.rmax+b.lmax),get(a.smax,a.rmax+b.lmax)}); c.tag = -inf; return c; } ll n,m,opt,x,y,z,i,a[N]; inline void build(ll s,ll t,ll p){ tr[p].tag = -inf; if(s==t){ tr[p].sum = tr[p].smax = tr[p].lmax = tr[p].rmax = (poly){1,a[s]},tr[p].s = inf; tr[p].minn = a[s],tr[p].sminn = inf; return ; } build(s,(s+t)/2,2*p),build((s+t)/2+1,t,2*p+1); tr[p] = merge(tr[2*p],tr[2*p+1]); } inline void pushtag(ll p,long long c){ if(c<=tr[p].minn) return ; long long delta = c-tr[p].minn; tr[p].minn=c,tr[p].tag=max(tr[p].tag,c),tr[p].s-=delta,tr[p].lmax.add(delta),tr[p].rmax.add(delta),tr[p].smax.add(delta),tr[p].sum.add(delta); } inline void pushdown(ll p){ if(tr[p].tag!=-inf){ pushtag(2*p,tr[p].tag),pushtag(2*p+1,tr[p].tag); tr[p].tag = -inf; } } inline void defeat(long long c,ll s,ll t,ll p){ if(c-tr[p].minn<=tr[p].s) return pushtag(p,c); pushdown(p); defeat(c,s,(s+t)/2,2*p),defeat(c,(s+t)/2+1,t,2*p+1); tr[p] = merge(tr[2*p],tr[2*p+1]); } inline void upd(ll l,ll r,ll c,ll s,ll t,ll p){ if(tr[p].minn>=c) return ; if(l<=s&&t<=r&&c<tr[p].sminn) return defeat(c,s,t,p); pushdown(p); if(l<=(s+t)/2) upd(l,r,c,s,(s+t)/2,2*p); if(r>(s+t)/2) upd(l,r,c,(s+t)/2+1,t,2*p+1); tr[p] = merge(tr[2*p],tr[2*p+1]); } inline node query(ll l,ll r,ll s,ll t,ll p){ if(l<=s&&t<=r) return tr[p]; pushdown(p); if(l<=(s+t)/2&&r>(s+t)/2) return merge(query(l,r,s,(s+t)/2,2*p),query(l,r,(s+t)/2+1,t,2*p+1)); else if(l<=(s+t)/2) return query(l,r,s,(s+t)/2,2*p); else return query(l,r,(s+t)/2+1,t,2*p+1); } int main(){
n=read(),m=read(); for(i=1;i<=n;i++) a[i]=read(); build(1,n,1); while(m--){
opt=read(); if(opt==0){ x=read(),y=read(),z=read(); upd(x,y,z,1,n,1); } else{ x=read(),y=read(); write(max(query(x,y,1,n,1).smax.b,0ll)),pc('\n'); } } fwrite(obuf,p3-obuf,1,stdout); return 0; }
|