30WA
感觉是细节出问题了但是找不出来
要瞎了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 1000005
#define INF 0x7fffffff
#define int long long
using namespace std;
int n,m,l,r,val,a[10000005];
struct node{
int lazyMax,lazyFMax,lazyUsedMax,lazyUsedFMax;
int l,r,Sum,Maxjs,usedMax,usedFMax,Maxx,FMaxx;
}Tree[maxn*4];
int read(){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
return s*w;
}
int Max(int x,int y){return x>y?x:y;}
int Min(int x,int y){return x<y?x:y;}
#define ls x<<1
#define rs x<<1|1
void pushup(int x){
Tree[x].Sum=Tree[ls].Sum+Tree[rs].Sum;
Tree[x].Maxx=Max(Tree[ls].Maxx,Tree[rs].Maxx);
Tree[x].usedMax=Max(Tree[ls].usedMax,Tree[rs].usedMax);
if(Tree[ls].Maxx==Tree[rs].Maxx){
Tree[x].FMaxx=Max(Tree[ls].FMaxx,Tree[rs].FMaxx);
Tree[x].Maxjs=Tree[ls].Maxjs+Tree[x].Maxjs;
}
if(Tree[ls].Maxx>Tree[rs].Maxx){
Tree[x].FMaxx=Max(Tree[rs].Maxx,Tree[ls].FMaxx);
Tree[x].Maxjs=Tree[ls].Maxjs;
}
if(Tree[ls].Maxx<Tree[rs].Maxx){
Tree[x].FMaxx=Max(Tree[ls].Maxx,Tree[rs].FMaxx);
Tree[x].Maxjs=Tree[rs].Maxjs;
}
}
void build(int x,int l,int r){
Tree[x].l=l;Tree[x].r=r;
if(l==r){
Tree[x].Sum=a[l];Tree[x].Maxx=a[l];
Tree[x].FMaxx=-INF;Tree[x].usedMax=a[l];
Tree[x].Maxjs=1;return;
}
int mid=l+r>>1;
build(ls,l,mid);build(rs,mid+1,r);
pushup(x);
}
void lazyUpdate(int LMax,int ULMax,int FLMax,int UFLMax,int x){
Tree[x].Sum+=LMax*Tree[x].Maxjs+FLMax*(Tree[x].r-Tree[x].l+1-Tree[x].Maxjs);
Tree[x].usedMax=Max(Tree[x].usedMax,Tree[x].Maxx+ULMax);
Tree[x].lazyUsedMax=Max(Tree[x].lazyUsedMax,Tree[x].lazyMax+ULMax);
Tree[x].lazyUsedFMax=Max(Tree[x].lazyUsedFMax,Tree[x].lazyFMax+UFLMax);
Tree[x].lazyMax+=LMax;
Tree[x].Maxx+=LMax;
Tree[x].lazyFMax+=FLMax;
Tree[x].FMaxx+=FLMax;
if(Tree[x].FMaxx!=-INF) Tree[x].usedFMax+=FLMax;
}
void pushdown(int x){
int GetMax=Max(Tree[ls].Maxx,Tree[rs].Maxx);
if(Tree[ls].Maxx==GetMax)
lazyUpdate(Tree[x].lazyMax,Tree[x].lazyUsedMax,Tree[x].lazyFMax,Tree[x].lazyUsedFMax,ls);
else lazyUpdate(Tree[x].lazyFMax,Tree[x].lazyUsedFMax,Tree[x].lazyFMax,Tree[x].lazyUsedFMax,ls);
if(Tree[rs].Maxx==GetMax)
lazyUpdate(Tree[x].lazyMax,Tree[x].lazyUsedMax,Tree[x].lazyFMax,Tree[x].lazyUsedFMax,rs);
else lazyUpdate(Tree[x].lazyFMax,Tree[x].lazyUsedFMax,Tree[x].lazyFMax,Tree[x].lazyUsedFMax,rs);
Tree[x].lazyMax=Tree[x].lazyFMax=Tree[x].lazyUsedMax=Tree[x].lazyUsedFMax=0;
}
void updateSum(int x){
if(l>Tree[x].r||r<Tree[x].l) return;
if(l<=Tree[x].l&&r>=Tree[x].r){lazyUpdate(val,val,val,val,x);return;}
pushdown(x);
updateSum(ls);updateSum(rs);
pushup(x);
}
void updateMin(int x){
if(l>Tree[x].r||r<Tree[x].l||val>=Tree[x].Maxx) return;
if(l<=Tree[x].l&&r>=Tree[x].r&&val>Tree[x].FMaxx){
lazyUpdate(val-Tree[x].Maxx,val-Tree[x].Maxx,0,0,x);
return ;
}
pushdown(x);
updateMin(ls);updateMin(rs);
pushup(x);
}
int query1(int x){
if(Tree[x].l>r||Tree[x].r<l) return 0;
if(l<=Tree[x].l&&r>=Tree[x].r) return Tree[x].Sum;
pushdown(x);
return query1(ls)+query1(rs);
}
int query2(int x){
if(Tree[x].l>r||Tree[x].r<l) return -INF;
if(l<=Tree[x].l&&r>=Tree[x].r) return Tree[x].Maxx;
pushdown(x);
return Max(query2(ls),query2(rs));
}
int query3(int x){
if(Tree[x].l>r||Tree[x].r<l) return -INF;
if(l<=Tree[x].l&&r>=Tree[x].r) return Tree[x].usedMax;
pushdown(x);
return Max(query3(ls),query3(rs));
}
signed main(){
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for(int i=1,opt;i<=m;i++){
opt=read();l=read();r=read();
if(opt==1){val=read();updateSum(1);}
if(opt==2){val=read();updateMin(1);}
if(opt==3) printf("%lld\n",query1(1));
if(opt==4) printf("%lld\n",query2(1));
if(opt==5) printf("%lld\n",query3(1));
// updateMaxAB(1,1,n,1,n);
}
return 0;
}