personpeople @ 2024-05-06 19:52:10
#include<iostream>
#include<climits>
using namespace std;
using ll=long long;
const int N=1e6+9;
ll a[N],t[N*4],lazy1[N*4];
bool lazy2[N*4];
int op,l,r,x,n,q;
inline int lc(int p){return p<<1;}
inline int rc(int p){return p<<1|1;}
void pushUp(int p){
t[p]=max(t[lc(p)],t[rc(p)]);
}
void buildTree(int p,int l,int r){
if(l==r){
t[p]=a[l];
return;
}
int mid=(l+r)>>1;
buildTree(lc(p),l,mid);
buildTree(rc(p),mid+1,r);
pushUp(p);
}
void movetag(int p,ll c){
t[p]+=c;
lazy1[p]+=c;
}
void change(int p,ll c){
lazy2[p]=1;
lazy1[p]=0;
t[p]=c;
}
void pushDown(int p){
if(lazy2[p]){
change(lc(p),t[p]);
change(rc(p),t[p]);
lazy2[p]=0;
}
else{
movetag(lc(p),lazy1[p]);
movetag(rc(p),lazy1[p]);
lazy1[p]=0;
}
}
void update(int p,int l,int r,int ql,int qr,ll c){
if(ql<=l&&r<=qr){
t[p]=c;
lazy1[p]=0;
lazy2[p]=1;
return ;
}
pushDown(p);
int mid=(l+r)>>1;
if(ql<=mid){
update(lc(p),l,mid,ql,qr,c);
}
if(mid<qr){
update(rc(p),mid+1,r,ql,qr,c);
}
pushUp(p);
}
void add(int p,int l,int r,int ql,int qr,ll c){
if(ql<=l&&r<=qr){
if(lazy2[p]){
pushDown(p);
}
t[p]+=c;
lazy1[p]+=c;
return ;
}
pushDown(p);
int mid=(l+r)>>1;
if(ql<=mid){
add(lc(p),l,mid,ql,qr,c);
}
if(mid<qr){
add(rc(p),mid+1,r,ql,qr,c);
}
pushUp(p);
}
ll query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){
return t[p];
}
pushDown(p);
int mid=(l+r)>>1;
ll ans=LLONG_MIN;
if(ql<=mid){
ans=max(ans,query(lc(p),l,mid,ql,qr));
}
if(mid<qr){
ans=max(ans,query(rc(p),mid+1,r,ql,qr));
}
return ans;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
}
buildTree(1,1,N);
while(q--){
cin>>op;
switch(op){
case 1:
cin>>l>>r>>x;
update(1,1,N,l,r,x);
break;
case 2:
cin>>l>>r>>x;
add(1,1,N,l,r,x);
break;
default:
cin>>l>>r;
cout<<query(1,1,N,l,r)<<endl;
}
}
return 0;
}