Heart_Moon @ 2024-08-08 18:53:24
#include <bits/stdc++.h>
using namespace std;
#define ls(x) (x<<1)
#define rs(x) (x<<1)+1
#define ll long long
//--------快读快写
inline ll read(){
ll num=0,f=1LL;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1LL;c=getchar();}
while(c>='0'&&c<='9'){num=num*10+(c-'0');c=getchar();}
return num*f;
}
inline void write(ll x){
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
//--------快读快写
const int N=1e6+50,sb=1e18;
ll n,q,a[N];
struct tree{
ll l,r,val,lazy,lazy_,maxn;//lazy存增加的,lazy_存修改的
}t[N<<2];
void pushup(ll x){
t[x].val=t[ls(x)].val+t[rs(x)].val;
t[x].maxn=max(t[ls(x)].maxn,t[rs(x)].maxn);//maxn设为两个子节点最大值的最大值
return;
}
void pushdown(ll x){
if(t[x].lazy_!=sb){//如果是修改就直接跳进来,修改完就润
t[ls(x)].lazy_=t[x].lazy_; t[ls(x)].val=t[x].lazy_;
t[rs(x)].lazy_=t[x].lazy_; t[rs(x)].val=t[x].lazy_;
t[ls(x)].maxn=t[x].lazy_; t[rs(x)].maxn=t[x].lazy_;
t[x].lazy_=sb; t[x].lazy=0;//重置lazy_和lazy,防止乱修改,
return;
}
t[ls(x)].val+=(t[ls(x)].r-t[ls(x)].l+1)*t[x].lazy;
t[rs(x)].val+=(t[rs(x)].r-t[rs(x)].l+1)*t[x].lazy;
t[ls(x)].lazy+=t[x].lazy;
t[rs(x)].lazy+=t[x].lazy;
t[ls(x)].maxn+=t[x].lazy;
t[rs(x)].maxn+=t[x].lazy;
t[x].lazy=0;
return;
//正常的push_back,不同的是如果处于这个区间,直接给maxn加lazytag就行
}
void build(ll l,ll r,ll x){
t[x].l=l; t[x].r=r;
t[x].lazy=0; t[x].lazy_=sb;//初始化两个lazytag
if(l==r){
t[x].val=a[l]; t[x].maxn=a[l];
//printf("%d %d %lld %lld\n",l,r,t[x].val,t[x].maxn);
return;
}
ll mid=(r-l)/2+l;
build(l,mid,ls(x)); build(mid+1,r,rs(x));
pushup(x);
return;
}
void alter(ll l,ll r,ll x,ll k){
if(t[x].l>r || t[x].r<l) return;
if(t[x].l>=l && t[x].r<=r){
t[x].val=(t[x].r-t[x].l+1)*k;
t[x].lazy_=k;
t[x].lazy=0;
t[x].maxn=k;
return;
}
pushdown(x);
alter(l,r,ls(x),k); alter(l,r,rs(x),k);
pushup(x);
return;
}
void add(ll l,ll r,ll x,ll k){
if(t[x].l>r || t[x].r<l) return;
if(t[x].l>=l && t[x].r<=r){
t[x].val+=(t[x].r-t[x].l+1)*k;
t[x].lazy+=k;
t[x].maxn+=k; return;//同上push_down
}
pushdown(x);
add(l,r,ls(x),k); add(l,r,rs(x),k);
pushup(x);
return;
}
ll ask(ll l,ll r,ll x){
if(t[x].l>r || t[x].r<l) return 0;
if(t[x].l>=l && t[x].r<=r){
return t[x].maxn;
}
pushdown(x);
return max(ask(l,r,ls(x)),ask(l,r,rs(x)));//返回区间最大的maxn
}
int main(){
//freopen("1253_6.in","r",stdin);
//freopen("1253_6.out","w",stdout);
n=read(); q=read();
for(ll i=1;i<=n;i++) a[i]=read();
build(1,n,1);
ll k,op,l,r;
for(ll i=1;i<=q;i++){
op=read(); l=read(); r=read();
if(op==1){
k=read();
alter(l,r,1,k);
}
if(op==2){
k=read();
add(l,r,1,k);
}
if(op==3){
write(ask(l,r,1));
printf("\n");
}
}
return 0;
}