题解:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const double eps=1e-8;
const int maxn=500100;
struct node
{
int l,r;
int maxx,maxl,se,cnt;
int addmaxx,addmaxl,addse,addsel;
ll sum;
}t[maxn<<2];
int a[maxn];
void pushup(int cnt)
{
t[cnt].maxx=max(t[lc].maxx,t[rc].maxx);
t[cnt].maxl=max(t[lc].maxl,t[rc].maxl);
t[cnt].sum=t[lc].sum+t[rc].sum;
if(t[lc].maxx==t[rc].maxx)
{
t[cnt].cnt=t[lc].cnt+t[rc].cnt;
t[cnt].se=max(t[lc].se,t[rc].se);
}
else if(t[lc].maxx>t[rc].maxx)
{
t[cnt].cnt=t[lc].cnt;
t[cnt].se=max(t[lc].se,t[rc].maxx);
}
else
{
t[cnt].cnt=t[rc].cnt;
t[cnt].se=max(t[lc].maxx,t[rc].se);
}
}
void update(int cnt,int addmaxx,int addmaxl,int addse,int addsel)
{
t[cnt].sum+=1ll*addmaxx*t[cnt].cnt+1ll*addse*(t[cnt].r-t[cnt].l+1-t[cnt].cnt);
t[cnt].maxl=max(t[cnt].maxl,t[cnt].maxx+addmaxl);
t[cnt].addmaxl=max(t[cnt].addmaxl,t[cnt].addmaxx+addmaxl);
t[cnt].maxx+=addmaxx;
t[cnt].addmaxx+=addmaxx;
t[cnt].addsel=max(t[cnt].addsel,t[cnt].addse+addsel);
if(t[cnt].se!=-inf) t[cnt].se+=addse;
t[cnt].addse+=addse;
}
void pushdown(int cnt)
{
int nowmaxx=max(t[lc].maxx,t[rc].maxx);
if(t[lc].maxx==nowmaxx) update(lc,t[cnt].addmaxx,t[cnt].addmaxl,t[cnt].addse,t[cnt].addsel);
else update(lc,t[cnt].addse,t[cnt].addsel,t[cnt].addse,t[cnt].addsel);
if(t[rc].maxx==nowmaxx) update(rc,t[cnt].addmaxx,t[cnt].addmaxl,t[cnt].addse,t[cnt].addsel);
else update(rc,t[cnt].addse,t[cnt].addsel,t[cnt].addse,t[cnt].addsel);
t[cnt].addmaxx=t[cnt].addmaxl=t[cnt].addse=t[cnt].addsel=0;
}
void build(int l,int r,int cnt)
{
t[cnt].l=l,t[cnt].r=r;
t[cnt].sum=t[cnt].maxx=t[cnt].maxl=t[cnt].se=t[cnt].cnt=0;
t[cnt].addmaxx=t[cnt].addmaxl=t[cnt].addse=t[cnt].addsel=0;
if(l==r)
{
t[cnt].sum=t[cnt].maxx=t[cnt].maxl=a[l];
t[cnt].se=-inf,t[cnt].cnt=1;
return ;
}
int mid=(l+r)>>1;
build(l,mid,lc);
build(mid+1,r,rc);
pushup(cnt);
}
void change1(int l,int r,int cnt,int k)
{
if(l<=t[cnt].l&&t[cnt].r<=r)
{
update(cnt,k,k,k,k);
return ;
}
pushdown(cnt);
if(l<=t[lc].r) change1(l,r,lc,k);
if(r>=t[rc].l) change1(l,r,rc,k);
pushup(cnt);
}
void change2(int l,int r,int cnt,int v)
{
if(v>=t[cnt].maxx) return ;
if(l<=t[cnt].l&&t[cnt].r<=r&&v>t[cnt].se)
{
update(cnt,v-t[cnt].maxx,v-t[cnt].maxx,0,0);
return ;
}
pushdown(cnt);
if(l<=t[lc].r) change2(l,r,lc,v);
if(r>=t[rc].l) change2(l,r,rc,v);
pushup(cnt);
}
ll ask3(int l,int r,int cnt)
{
if(l<=t[cnt].l&&t[cnt].r<=r)
return t[cnt].sum;
pushdown(cnt);
ll ans=0;
if(l<=t[lc].r) ans+=ask3(l,r,lc);
if(r>=t[rc].l) ans+=ask3(l,r,rc);
return ans;
}
int ask4(int l,int r,int cnt)
{
if(l<=t[cnt].l&&t[cnt].r<=r)
return t[cnt].maxx;
pushdown(cnt);
int maxx=-inf;
if(l<=t[lc].r) maxx=max(maxx,ask4(l,r,lc));
if(r>=t[rc].l) maxx=max(maxx,ask4(l,r,rc));
return maxx;
}
int ask5(int l,int r,int cnt)
{
if(l<=t[cnt].l&&t[cnt].r<=r)
return t[cnt].maxl;
pushdown(cnt);
int maxx=-inf;
if(l<=t[lc].r) maxx=max(maxx,ask5(l,r,lc));
if(r>=t[rc].l) maxx=max(maxx,ask5(l,r,rc));
return maxx;
}
int main(void)
{
int n,m;
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,v;
for(int i=1;i<=m;i++)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%d",&l,&r,&k);
change1(l,r,1,k);
}
else if(op==2)
{
scanf("%d%d%d",&l,&r,&v);
change2(l,r,1,v);
}
else if(op==3)
{
scanf("%d%d",&l,&r);
printf("%lld\n",ask3(l,r,1));
}
else if(op==4)
{
scanf("%d%d",&l,&r);
printf("%d\n",ask4(l,r,1));
}
else if(op==5)
{
scanf("%d%d",&l,&r);
printf("%d\n",ask5(l,r,1));
}
}
return 0;
}