刚学线段树, 50pts,5AC+5WA
。
#include<cstdio>
#include<algorithm>
using namespace std;
int n,q,o,a,b,kx,f[1000025];
struct Tre{
int l,r;
long long vl,t1,t2;
};
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 push_down(int x){
if(s[x].t1==-2e9 && s[x].t2==0)return;
if(s[x].t1!=-2e9){
s[ls(x)].vl=s[rs(x)].vl=s[ls(x)].t1=s[rs(x)].t1=s[x].t1;
s[ls(x)].t2=s[rs(x)].t2=0;
s[x].t1=-2e9;
}
s[ls(x)].vl+=s[x].t2;
s[rs(x)].vl+=s[x].t2;
s[ls(x)].t2+=s[x].t2;
s[rs(x)].t2+=s[x].t2;
s[x].t2=0;
return;
}
void build(int l,int r,int x){
s[x].l=l,s[x].r=r,s[x].t1=-2e9;
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>=l && s[x].r<=r){
s[x].vl=k;
s[x].t1=k;
s[x].t2=0;
return;
}
push_down(x);
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>=l && s[x].r<=r){
s[x].vl+=k;
s[x].t2+=k;
return;
}
push_down(x);
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 -1e9;
if(s[x].l>=l && s[x].r<=r)return s[x].vl;
push_down(x);
return max(ask(l,r,ls(x)),ask(l,r,rs(x)));
}
// void print(int x){
// printf("%d %d %lld %d %d\n",s[x].l,s[x].r,s[x].vl,s[x].t1,s[x].t2);
// if(s[x].l==s[x].r)return;
// print(ls(x)),print(rs(x));
// return;
// }
}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);
//printf("\n+++\n");
//seg.print(1);
//printf("\n+++\n");
}
return 0;
}