额让我们来看看都有些什么操作,区间加权,区间取min......
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=5e5+10,M=N<<2,inf=1e18;
ll n,m,sum[M],mxa[M],mxb[M],se[M],t[M];
ll la[M],lax[M],lb[M],lbx[M];
void Merge(ll x,ll L,ll R){
sum[x]=sum[x*2]+sum[x*2+1];
mxa[x]=max(mxa[x*2],mxa[x*2+1]);
mxb[x]=max(mxb[x*2],mxb[x*2+1]);
if(mxa[x*2]==mxa[x*2+1]){
t[x]=t[x*2]+t[x*2+1];
se[x]=max(se[x*2],se[x*2+1]);
}
else if(mxa[x*2]<mxa[x*2+1]){
t[x]=t[x*2+1];
se[x]=max(mxa[x*2],se[x*2+1]);
}
else if(mxa[x*2]>mxa[x*2+1]){
t[x]=t[x*2];
se[x]=max(se[x*2],mxa[x*2+1]);
}
return;
}
void Updata(ll x,ll len,ll a,ll b,ll c,ll d){
sum[x]+=a*(len-t[x])+b*t[x];
mxb[x]=max(mxb[x],mxa[x]+d);
lbx[x]=max(lbx[x],lax[x]+d);
lb[x]=max(lb[x],la[x]+c);
mxa[x]+=b;lax[x]+=b;la[x]+=a;
if(se[x]!=-inf)se[x]+=a;
}
void Downdata(ll x,ll L,ll R){
ll mid=(L+R)>>1,maxn=max(mxa[x*2],mxa[x*2+1]);
if(mxa[x*2]==maxn)
Updata(x*2,mid-L+1,la[x],lax[x],lb[x],lbx[x]);
else
Updata(x*2,mid-L+1,la[x],la[x],lb[x],lb[x]);
if(mxa[x*2+1]==maxn)
Updata(x*2+1,R-mid,la[x],lax[x],lb[x],lbx[x]);
else
Updata(x*2+1,R-mid,la[x],la[x],lb[x],lb[x]);
la[x]=lax[x]=lb[x]=lbx[x]=0;
return;
}
void ChangeAdd(ll x,ll L,ll R,ll l,ll r,ll val){
if(L==l&&R==r){Updata(x,R-L+1,val,val,val,val);return;}
ll mid=(L+R)>>1;Downdata(x,L,R);
if(r<=mid)ChangeAdd(x*2,L,mid,l,r,val);
else if(l>mid)ChangeAdd(x*2+1,mid+1,R,l,r,val);
else ChangeAdd(x*2,L,mid,l,mid,val),ChangeAdd(x*2+1,mid+1,R,mid+1,r,val);
Merge(x,L,R);return;
}
void ChangeMin(ll x,ll L,ll R,ll l,ll r,ll val){
ll mid=(L+R)>>1;
if(val>=mxa[x])return;
if(L==l&&R==r){
if(val>se[x]){
Updata(x,R-L+1,0,val-mxa[x],0,val-mxa[x]);
return;
}
Downdata(x,L,R);
ChangeMin(x*2,L,mid,l,mid,val);
ChangeMin(x*2+1,mid+1,R,mid+1,r,val);
Merge(x,L,R);return;
}
Downdata(x,L,R);
if(r<=mid)ChangeMin(x*2,L,mid,l,r,val);
else if(l>mid)ChangeMin(x*2+1,mid+1,R,l,r,val);
else ChangeMin(x*2,L,mid,l,mid,val),ChangeMin(x*2+1,mid+1,R,mid+1,r,val);
Merge(x,L,R);
}
ll AskSum(ll x,ll L,ll R,ll l,ll r){
if(L==l&&R==r)return sum[x];
ll mid=(L+R)>>1;Downdata(x,L,R);
if(r<=mid)return AskSum(x*2,L,mid,l,r);
if(l>mid)return AskSum(x*2+1,mid+1,R,l,r);
return AskSum(x*2,L,mid,l,mid)+AskSum(x*2+1,mid+1,R,mid+1,r);
}
ll AskMaxa(ll x,ll L,ll R,ll l,ll r){
if(L==l&&R==r)return mxa[x];
ll mid=(L+R)>>1;Downdata(x,L,R);
if(r<=mid)return AskMaxa(x*2,L,mid,l,r);
if(l>mid)return AskMaxa(x*2+1,mid+1,R,l,r);
return max(AskMaxa(x*2,L,mid,l,mid),AskMaxa(x*2+1,mid+1,R,mid+1,r));
}
ll AskMaxb(ll x,ll L,ll R,ll l,ll r){
if(L==l&&R==r)return mxb[x];
ll mid=(L+R)>>1;Downdata(x,L,R);
if(r<=mid)return AskMaxb(x*2,L,mid,l,r);
if(l>mid)return AskMaxb(x*2+1,mid+1,R,l,r);
return max(AskMaxb(x*2,L,mid,l,mid),AskMaxb(x*2+1,mid+1,R,mid+1,r));
}
void Build(ll x,ll L,ll R){
if(L==R){
ll w;scanf("%lld",&w);
mxa[x]=mxb[x]=sum[x]=w;
se[x]=-inf;t[x]=1;
return;
}
ll mid=(L+R)>>1;
Build(x*2,L,mid);
Build(x*2+1,mid+1,R);
Merge(x,L,R);
return;
}
signed main()
{
scanf("%lld%lld",&n,&m);
Build(1,1,n);
while(m--){
ll op,l,r,w;
scanf("%lld%lld%lld",&op,&l,&r);
if(op==1){scanf("%lld",&w);ChangeAdd(1,1,n,l,r,w);}
if(op==2){scanf("%lld",&w);ChangeMin(1,1,n,l,r,w);}
if(op==3)printf("%lld\n",AskSum(1,1,n,l,r));
if(op==4)printf("%lld\n",AskMaxa(1,1,n,l,r));
if(op==5)printf("%lld\n",AskMaxb(1,1,n,l,r));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?