liuenyin @ 2023-07-30 21:42:05
AC on #1 and #3,代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long INF=0x7ffffffffffffff;
struct segment_tree{
struct node{
ll l,r,w;//w: max
ll lazytag_1,lazytag_2;//懒标记
node(){
lazytag_1=lazytag_2=-INF;
}
};
node tree[4000005];//线段树开4倍空间
ll arr[1000005];
void build(int l,int r,int p){
// 左 右 根
tree[p].l=l;
tree[p].r=r;
if(l==r){
tree[p].w=arr[l];
//arr为原数组
return;
}
int mid=(l+r)/2;
build(l,mid,p*2);//建立左子树
build(mid+1,r,p*2+1);//建立右子树
tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
}
void pushdown_1(int p){
//懒标记下传(opt=1) 即将区间内的值设为x
if(tree[p].lazytag_1!=-INF){
tree[p*2].w = tree[p].lazytag_1;
tree[p*2+1].w=tree[p].lazytag_1;
tree[p*2].lazytag_1=tree[p].lazytag_1;
tree[p*2+1].lazytag_1=tree[p].lazytag_1;
tree[p].lazytag_1=-INF;
}
}
void pushdown_2(int p){
//懒标记下传(opt=2) 即将区间内的值增加x
if(tree[p].lazytag_2!=-INF){
tree[p*2].w+=tree[p].lazytag_2;
tree[p*2+1].w+=tree[p].lazytag_2;
tree[p*2].lazytag_2+=tree[p].lazytag_2;
tree[p*2+1].lazytag_2+=tree[p].lazytag_2;
tree[p].lazytag_2=-INF;
}
}
void update_1(int l,int r,int p,int x){
//更新区间的值(opt=1)
if(l<=tree[p].l and r>=tree[p].r){
tree[p].w=x;
tree[p].lazytag_1=x;
return;
}
pushdown_1(p);
int mid=(tree[p].l+tree[p].r)/2;
if(l<=mid)update_1(l,r,p*2,x);
if(r>mid)update_1(l,r,p*2+1,x);
tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
}
void update_2(int l,int r,int p,int x){
//更新区间的值 (opt=2)
if(l<=tree[p].l and r>=tree[p].r){
tree[p].w+=x;
tree[p].lazytag_2+=x;
return;
}
pushdown_2(p);
int mid=(tree[p].l+tree[p].r)/2;
if(l<=mid)update_2(l,r,p*2,x);
if(r>mid)update_2(l,r,p*2+1,x);
tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
}
ll query(int l,int r,int p){
//查询区间的值
if(l<=tree[p].l and r>=tree[p].r){
return tree[p].w;
}
// pushdown_1(p);
pushdown_2(p);
ll mid=(tree[p].l+tree[p].r)/2,ans=-INF;
if(l<=mid)ans=max(ans,query(l,r,p*2));
if(r>mid)ans=max(ans,query(l,r,p*2+1));
return ans;
}
};
segment_tree t;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%lld",&t.arr[i]);
}
t.build(1,n,1);
int op,l,r,x;
for(int i=1;i<=m;i++){
cin>>op>>l>>r;
//cout<<op<<" "<<l<<" "<<r<<endl;
if(op==1||op==2)cin>>x;
if(op==1){
t.update_1(l,r,1,x);
}
else if(op==2){
t.update_2(l,r,1,x);
}
else{
cout<<t.query(l,r,1)<<endl;
}
}
return 0;
}