D_FANG @ 2023-07-20 18:14:32
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long max(long long a,long long b){
return a>b?a:b;
}
int read(){
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9'){
if (c=='-') f=-1;
c=getchar();
}
while (c>='0'&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
struct trees{
int l,r,lz,op,mlz;
long long maxn;
}tree[8000010];
int n,q;
int a[1000010];
void build(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
tree[i].lz=0;
tree[i].op=0;
tree[i].mlz=0;
if (l==r){
tree[i].maxn=a[l];
return ;
}
int mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn);
return ;
}
void pushdown(int i){
if (tree[i].op!=0){
tree[i].op=0;
tree[i*2].op=1;
tree[i*2+1].op=1;
tree[i*2].lz=0;
tree[i*2+1].lz=0;
tree[i*2].mlz=tree[i].mlz;
tree[i*2+1].mlz=tree[i].mlz;
tree[i*2].maxn=tree[i].mlz;
tree[i*2+1].maxn=tree[i].mlz;
tree[i].mlz=0;
}
if (tree[i].lz!=0){
tree[i*2].lz+=tree[i].lz;
tree[i*2+1].lz+=tree[i].lz;
tree[i*2].maxn+=tree[i].lz;
tree[i*2+1].maxn+=tree[i].lz;
tree[i].lz=0;
}
return ;
}
long long query(int i,int l,int r){
if (tree[i].l>=l&&tree[i].r<=r){
return tree[i].maxn;
}
if (tree[i].l>r||tree[i].r<l){
return -1e18;
}
pushdown(i);
long long s=-1e18;
if (tree[i*2].r>=l) s=max(s,query(i*2,l,r));
if (tree[i*2+1].l<=r) s=max(s,query(i*2+1,l,r));
return s;
}
void add1(int i,int l,int r,int x){
if (tree[i].l>=l&&tree[i].r<=r){
// pushdown(i);
if (tree[i].op!=0){
tree[i].op=0;
tree[i*2].op=1;
tree[i*2+1].op=1;
tree[i*2].lz=0;
tree[i*2+1].lz=0;
tree[i*2].mlz=tree[i].mlz;
tree[i*2+1].mlz=tree[i].mlz;
tree[i*2].maxn=tree[i].mlz;
tree[i*2+1].maxn=tree[i].mlz;
tree[i].mlz=0;
}
tree[i].maxn+=x;
tree[i].lz+=x;
return ;
}
if (tree[i].r<l||tree[i].l>r) return ;
pushdown(i);
if (tree[i*2].r>=l) add1(i*2,l,r,x);
if (tree[i*2+1].l<=r) add1(i*2+1,l,r,x);
tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn);
return ;
}
void add2(int i,int l,int r,int x){
if (tree[i].l>=l&&tree[i].r<=r){
tree[i].maxn=x;
tree[i].lz=0;
tree[i].mlz=x;
tree[i].op=1;
return ;
}
if (tree[i].r<l||tree[i].l>r) return ;
pushdown(i);
if (tree[i*2].r>=l) add2(i*2,l,r,x);
if (tree[i*2+1].l<=r) add2(i*2+1,l,r,x);
tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn);
return ;
}
int main(){
n=read();
q=read();
for (int i=1;i<=n;i++){
a[i]=read();
}
build(1,1,n);
for (int i=1;i<=q;i++){
int op;
op=read();
if (op==1){
int x,y,z;
x=read();
y=read();
z=read();
add2(1,x,y,z);
}
if (op==2){
int x,y,z;
x=read();
y=read();
z=read();
add1(1,x,y,z);
}
if (op==3){
int x,y;
x=read();
y=read();
printf("%lld\n",query(1,x,y));
}
}
return 0;
}
by D_FANG @ 2023-07-20 18:16:06
add1说的是修改,add2说的是覆盖,op标志着有没有修改操作进行,mlz存储要修改成的值