RT,mine是当前最大值,maxe是历史最大值,ls是左孩子,rs是右孩子,second是严格次大值
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=5e5+10;
struct node{
int ls,rs,maxe,mine,l,r,second,cnt,lazy1,lazy2,lazy3,lazy4;
long long sum;
}tree[4*MAXN];
int a[4*MAXN];
int tot=1;
inline void lazy(int a1,int a2,int a3,int a4,int p)
{
tree[p].sum+=1LL*a1*tree[p].cnt+1LL*a2*(tree[p].r-tree[p].l+1-tree[p].cnt);
tree[p].maxe=max(tree[p].maxe,tree[p].mine+a3);
tree[p].mine+=a1;
if(tree[p].second!=-1e18)
tree[p].second+=a2;
tree[p].lazy3=max(tree[p].lazy3,tree[p].lazy1+a3);
tree[p].lazy4=max(tree[p].lazy4,tree[p].lazy2+a4);
tree[p].lazy1+=a1;
tree[p].lazy2+=a2;
}
inline void pushdown(int p)
{
int l=tree[p].ls,r=tree[p].rs;
int maxx=max(tree[l].mine,tree[r].mine);
if(tree[l].mine==maxx)
lazy(tree[p].lazy1,tree[p].lazy2,tree[p].lazy3,tree[p].lazy4,tree[p].ls);
else
lazy(tree[p].lazy2,tree[p].lazy2,tree[p].lazy4,tree[p].lazy4,tree[p].ls);
if(tree[r].mine==maxx)
lazy(tree[p].lazy1,tree[p].lazy2,tree[p].lazy3,tree[p].lazy4,tree[p].rs);
else
lazy(tree[p].lazy2,tree[p].lazy2,tree[p].lazy4,tree[p].lazy4,tree[p].rs);
tree[p].lazy1=tree[p].lazy2=tree[p].lazy3=tree[p].lazy4=0;
}
inline void pushup(int p)
{
int l=tree[p].ls,r=tree[p].rs;
tree[p].sum=tree[l].sum+tree[r].sum;
tree[p].mine=max(tree[l].mine,tree[r].mine);
tree[p].maxe=max(tree[l].maxe,tree[r].maxe);
if(tree[l].mine==tree[r].mine)
{
tree[p].second=max(tree[l].second,tree[r].second);
tree[p].cnt=tree[l].cnt+tree[r].cnt;
}
if(tree[l].mine>tree[r].mine)
{
tree[p].second=max(tree[l].second,tree[r].mine);
tree[p].cnt=tree[l].cnt;
}
if(tree[l].mine<tree[r].mine)
{
tree[p].second=max(tree[l].mine,tree[r].second);
tree[p].cnt=tree[r].cnt;
}
}
inline void modify(int p,int l,int r,int k)
{
if(l<=tree[p].l&&tree[p].r<=r)
{
tree[p].sum+=(tree[p].r-tree[p].l+1)*k;
tree[p].maxe=max(tree[p].maxe,tree[p].mine+k);
tree[p].mine+=k;
if(tree[p].second!=-1e18)
tree[p].second+=k;
tree[p].lazy1+=k;
tree[p].lazy2+=k;
tree[p].lazy3=max(tree[p].lazy3,tree[p].lazy1);
tree[p].lazy4=max(tree[p].lazy4,tree[p].lazy2);
return ;
}
if(tree[p].l==-1)
return ;
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid)
modify(tree[p].ls,l,r,k);
if(mid<r)
modify(tree[p].rs,l,r,k);
pushup(p);
return ;
}
inline long long sigma(int p,int l,int r)
{
if(l<=tree[p].l&&tree[p].r<=r)
return tree[p].sum;
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1;
long long ans=0;
if(l<=mid)
ans+=sigma(tree[p].ls,l,r);
if(mid<r)
ans+=sigma(tree[p].rs,l,r);
return ans;
}
inline int minn(int p,int l,int r)
{
if(l<=tree[p].l&&tree[p].r<=r)
return tree[p].mine;
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1,ans=-1e18;
if(l<=mid)
ans=max(ans,minn(tree[p].ls,l,r));
if(mid<r)
ans=max(ans,minn(tree[p].rs,l,r));
return ans;
}
inline int maxn(int p,int l,int r)
{
if(l<=tree[p].l&&tree[p].r<=r)
return tree[p].maxe;
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1,ans=-1e18;
if(l<=mid)
ans=max(ans,maxn(tree[p].ls,l,r));
if(mid<r)
ans=max(ans,maxn(tree[p].rs,l,r));
return ans;
}
inline void change(int p,int l,int r,int k)
{
if(l<=tree[p].l&&tree[p].r<=r&&tree[p].second<k)
{
int v=tree[p].mine-k;
tree[p].sum-=v*tree[p].cnt;
tree[p].mine=k;
tree[p].lazy1-=v;
return ;
}
if(tree[p].ls==-1)
return ;
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid)
change(tree[p].ls,l,r,k);
if(mid<r)
change(tree[p].rs,l,r,k);
pushup(p);
}
inline void build(int p,int l,int r)
{
tree[p].l=l;
tree[p].r=r;
if(l==r)
{
tree[p].sum=tree[p].maxe=tree[p].mine=a[l];
tree[p].ls=tree[p].rs=-1;
tree[p].second=-1e18;
tree[p].cnt=1;
return ;
}
tot++;
int mid=l+r>>1;
tree[p].ls=tot;
build(tot,l,mid);
tot++;
tree[p].rs=tot;
build(tot,mid+1,r);
pushup(p);
}
signed main()
{
int n,m;
scanf("%lld%lld",&n,&m);
for(int i(1);i<=n;++i)
scanf("%lld",&a[i]);
build(1,1,n);
while(m--)
{
int op,l,r,k;
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld%lld",&l,&r,&k);
modify(1,l,r,k);
}
if(op==2)
{
scanf("%lld%lld%lld",&l,&r,&k);
change(1,l,r,k);
}
if(op==3)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",sigma(1,l,r));
}
if(op==4)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",minn(1,l,r));
}
if(op==5)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",maxn(1,l,r));
}
}
return 0;
}