HeYilin @ 2023-12-31 09:12:08
#include<bits/stdc++.h>
typedef long long int ll;
using namespace std;
const int maxn=1e6+10;
const ll _INF=LLONG_MIN;
ll n,m,a[maxn],op,x,y,k;
struct SegmentTree{
ll l,r;
ll mx;
ll tag1,tag2;
}t[maxn<<2];
void build(ll p,ll l,ll r){
t[p].l=l,t[p].r=r,t[p].tag1=_INF;
if(l==r){t[p].mx=a[l];return;}
ll mid=l+r>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
}
void spread1(ll p){//lazy to be x
if(t[p].tag1!=_INF){
t[p*2].mx=t[p*2].tag1=t[p].tag1;
t[p*2+1].mx=t[p*2+1].tag1=t[p].tag1;
t[p*2].tag2=t[p*2+1].tag2=0;
t[p].tag1=_INF;
}
}
void spread2(ll p){//lazy add x
if(t[p].tag2){
spread1(p);
t[p*2].mx+=t[p].tag2;
t[p*2].tag2+=t[p].tag2;
t[p*2+1].mx+=t[p].tag2;
t[p*2+1].tag2+=t[p].tag2;
t[p].tag2=0;
}
}
void change1(ll p,ll l,ll r,ll d){//to be x
if(l<=t[p].l&&r>=t[p].r){
t[p].mx=t[p].tag1=d;
t[p].tag2=0;
return;
}
spread1(p);
ll mid=t[p].l+t[p].r>>1;
if(l<=mid)change1(p*2,l,r,d);
if(r>mid)change1(p*2+1,l,r,d);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
}
void change2(ll p,ll l,ll r,ll d){//add x
if(l<=t[p].l&&r>=t[p].r){
spread1(p);
t[p].mx+=d;
t[p].tag2+=d;
return;
}
spread2(p);
ll mid=t[p].l+t[p].r>>1;
if(l<=mid)change2(p*2,l,r,d);
if(r>mid)change2(p*2+1,l,r,d);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
}
ll query(ll p,ll l,ll r){//ask for max
if(l<=t[p].l&&r>=t[p].r)return t[p].mx;
spread2(p);
ll mid=t[p].l+t[p].r>>1;
ll val=LLONG_MIN;
if(l<=mid)val=max(val,query(p*2,l,r));
if(r>mid)val=max(val,query(p*2+1,l,r));
return val;
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
while(m--){
scanf("%lld%lld%lld",&op,&x,&y);
if(op==1){
scanf("%lld",&k);
change1(1,x,y,k);
}
if(op==2){
scanf("%lld",&k);
change2(1,x,y,k);
}
if(op==3)printf("%lld\n",query(1,x,y));
}
return 0;
}
/*
4 4
10 4 -3 -7
1 1 3 0
2 3 4 -4
1 2 4 -9
3 1 4
*/