2022_37_yzyUUU @ 2024-02-17 18:57:48
#include <bits/stdc++.h>
#define void inline void
#define int long long
#define N 100005
using namespace std;
int a[N],l[4*N],r[4*N],ma[4*N],cag_tag[4*N],add_tag[4*N],n,q;
void build(int p,int nl,int nr){
l[p]=nl,r[p]=nr;
if(nl==nr){
ma[p]=a[nl];
return;
}
int mid=nl+nr>>1;
build(p<<1,nl,mid);
build(p<<1|1,mid+1,nr);
ma[p]=max(ma[p<<1],ma[p<<1|1]);
}
void down_add(int p){
if(add_tag[p]){
ma[p<<1]+=add_tag[p];
ma[p<<1|1]+=add_tag[p];
add_tag[p<<1]+=p;
add_tag[p<<1|1]+=p;
add_tag[p]=0;
}
}
void down_cag(int p){
if(cag_tag[p]){
ma[p<<1]=cag_tag[p];
ma[p<<1|1]=cag_tag[p];
cag_tag[p<<1]=p;
cag_tag[p<<1|1]=p;
cag_tag[p]=0;
}
}
void add(int p,int gl,int gr,int x){
if(gl<=l[p]&&r[p]<=gr){
add_tag[p]+=x;
ma[p]+=x;
return;
}
down_cag(p);
down_add(p);
int mid=l[p]+r[p]>>1;
if(gl<=mid)add(p<<1,gl,gr,x);
if(gr>mid)add(p<<1|1,gl,gr,x);
ma[p]=max(ma[p<<1],ma[p<<1|1]);
}
void change(int p,int gl,int gr,int x){
if(gl<=l[p]&&r[p]<=gr){
add_tag[p]=x;
ma[p]=x;
return;
}
down_cag(p);
down_add(p);
int mid=l[p]+r[p]>>1;
if(gl<=mid)change(p<<1,gl,gr,x);
if(gr>mid)change(p<<1|1,gl,gr,x);
ma[p]=max(ma[p<<1],ma[p<<1|1]);
}
int ask(int p,int gl,int gr){
if(gl<=l[p]&&r[p]<=gr){
return ma[p];
}
down_cag(p);
down_add(p);
int mid=l[p]+r[p]>>1,ans1=INT_MIN,ans2=INT_MIN;
if(gl<=mid)ans1=max(ans1,ask(p<<1,gl,gr));
if(gr>mid)ans2=max(ans2,ask(p<<1|1,gl,gr));
return max(ans1,ans2);
}
signed main() {
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
for(int i=1;i<=q;i++){
int op,l,r,x;
cin>>op>>l>>r;
if(op==1){
cin>>x;
change(1,l,r,x);
}
if(op==2){
cin>>x;
add(1,l,r,x);
}
if(op==3)
cout<<ask(1,l,r)<<"\n";
}
}
by 杜都督 @ 2024-02-17 19:25:06
这道题的懒惰标记不能这么处理
根据逻辑可以推断出修改标记和增加标记不会同时出现
因为当执行增加操作时,若节点已有修改标记,则直接将修改标记增加对应的值即可,无须改动增加标记,否则再改动增加标记
而当执行修改操作时,需将增加标记清空
所以你需要修正一下添加和下传懒惰标记的逻辑