目前只写了操作1、3、4、5,我太蒟了,线段树板子都不会(吉司机线段树没有操作2,没有了吉司机,就只剩线段树了)
#include<bits/stdc++.h>
using namespace std;
#define p2 (p<<1)
#define p3 ((p<<1)|1)
typedef long long ll;
const int N=5e5+5;
int n,m,a[N],lz[N<<2],mxlz[N<<2];
struct xx{
int mx,b;ll sum;
}tr[N<<2];
inline xx merge(xx x,xx y){
return {max(x.mx,y.mx),max(x.b,y.b),x.sum+y.sum};
}
inline void pu(int p){
tr[p]=merge(tr[p2],tr[p3]);
}
void build(int l,int r,int p){
if(l==r){
tr[p].sum=tr[p].mx=tr[p].b=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,p2),build(mid+1,r,p3);
pu(p);
}
inline void jia(int l,int r,int p,int k){
tr[p].mx+=k,tr[p].sum+=1ll*(r-l+1)*k;
lz[p]+=k,mxlz[p]=max(mxlz[p],lz[p]);
}
inline void pd(int l,int r,int p){
if(lz[p]==0&&mxlz[p]==0) return;
int mid=(l+r)>>1;
jia(l,mid,p2,lz[p]),jia(mid+1,r,p3,lz[p]);
tr[p2].b+=mxlz[p],tr[p3].b+=mxlz[p];
lz[p]=mxlz[p]=0;
}
void add(int l,int r,int p,int nl,int nr,int k){
if(l==nl&&r==nr){
jia(l,r,p,k),tr[p].b=max(tr[p].b,tr[p].mx);
return;
}
pd(l,r,p);
int mid=(l+r)>>1;
if(nr<=mid) add(l,mid,p2,nl,nr,k);
else if(nl>mid) add(mid+1,r,p3,nl,nr,k);
else add(l,mid,p2,nl,mid,k),add(mid+1,r,p3,mid+1,nr,k);
pu(p);
}
ll qiusum(int l,int r,int p,int nl,int nr){
if(l==nl&&r==nr) return tr[p].sum;
pd(l,r,p);
int mid=(l+r)>>1;ll res;
if(nr<=mid) res=qiusum(l,mid,p2,nl,nr);
else if(nl>mid) res=qiusum(mid+1,r,p3,nl,nr);
else res=qiusum(l,mid,p2,nl,mid)+qiusum(mid+1,r,p3,mid+1,nr);
pu(p);
return res;
}
int qiumx(int l,int r,int p,int nl,int nr){
if(l==nl&&r==nr) return tr[p].mx;
pd(l,r,p);
int mid=(l+r)>>1,res;
if(nr<=mid) res=qiumx(l,mid,p2,nl,nr);
else if(nl>mid) res=qiumx(mid+1,r,p3,nl,nr);
else res=max(qiumx(l,mid,p2,nl,mid),qiumx(mid+1,r,p3,mid+1,nr));
pu(p);
return res;
}
int qiub(int l,int r,int p,int nl,int nr){
if(l==nl&&r==nr) return tr[p].b;
pd(l,r,p);
int mid=(l+r)>>1,res;
if(nr<=mid) res=qiub(l,mid,p2,nl,nr);
else if(nl>mid) res=qiub(mid+1,r,p3,nl,nr);
else res=max(qiub(l,mid,p2,nl,mid),qiub(mid+1,r,p3,mid+1,nr));
pu(p);
return res;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,n,1);
int op,l,r,k;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&op,&l,&r);
if(op==1){
scanf("%d",&k);
add(1,n,1,l,r,k);
}else if(op==2){
scanf("%d",&k);
continue;
}else if(op==3){
printf("%lld\n",qiusum(1,n,1,l,r));
}else if(op==4){
printf("%d\n",qiumx(1,n,1,l,r));
}else printf("%d\n",qiub(1,n,1,l,r));
}
return 0;
}