刚学线段树。AC+WA+AC+WA+6TLE
。
#include<cstdio>
#include<algorithm>
using namespace std;
int n,q,o,a,b,kx,f[1000025];
struct Tre{
int l,r;
long long vl;
};
int ls(int x){return x<<1;}
int rs(int x){return (x<<1)+1;}
struct Seg{
Tre s[4000025];
void push_up(int x){
s[x].vl=max(s[ls(x)].vl,s[rs(x)].vl);
return;
}
void build(int l,int r,int x){
s[x].l=l,s[x].r=r;
if(l==r){
s[x].vl=f[l];
return;
}
int mid=(l+r)/2;
build(l,mid,ls(x)),build(mid+1,r,rs(x));
push_up(x);
return;
}
void op1(int l,int r,int x,int k){
if(s[x].l>r || s[x].r<l)return;
if(s[x].l==s[x].r){
s[x].vl=k;
return;
}
op1(l,r,ls(x),k),op1(l,r,rs(x),k);
push_up(x);
return;
}
void op2(int l,int r,int x,int k){
if(s[x].l>r || s[x].r<l)return;
if(s[x].l==s[x].r){
s[x].vl+=k;
return;
}
op2(l,r,ls(x),k),op2(l,r,rs(x),k);
push_up(x);
return;
}
long long ask(int l,int r,int x){
if(s[x].l>r || s[x].r<l)return -2147483648;
if(s[x].l>=l || s[x].r<=r)return s[x].vl;
return max(ask(l,r,ls(x)),ask(l,r,rs(x)));
}
}seg;
int main(){
scanf("%d %d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d",&f[i]);
seg.build(1,n,1);
for(int i=1;i<=q;i++){
scanf("%d %d %d",&o,&a,&b);
if(o==1){
scanf("%d",&kx);
seg.op1(a,b,1,kx);
}
if(o==2){
scanf("%d",&kx);
seg.op2(a,b,1,kx);
}
if(o==3){
printf("%lld\n",seg.ask(a,b,1));
}
//for(int i=1;i<=10;i++)printf("%d %d %d\n",seg.s[i].l,seg.s[i].r,seg.s[i].vl);
}
return 0;
}