pushup:t[k].max=max(t[k<<1].max,t[k<<1|1].max,t[k<<1].rmax+t[k<<1|1].lmax);
注意查询,如果所要找的区间恰好在左区间或右区间中,则直接查找。否则和pushup中一样操作。
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=500005;
ll a[N];
int n,m;
ll read(){
ll num=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
num=num*10+c-'0';
c=getchar();
}
return num*f;
}
struct node{
ll lmax,rmax,sum,max;
}t[N<<2];
ll maxx(ll x,ll y,ll z){
return max(x,max(y,z));
}
void pushup(int k){
t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
t[k].lmax=max(t[k<<1].lmax,t[k<<1].sum+t[k<<1|1].lmax);
t[k].rmax=max(t[k<<1|1].rmax,t[k<<1].rmax+t[k<<1|1].sum);
t[k].max=maxx(t[k<<1].max,t[k<<1|1].max,t[k<<1].rmax+t[k<<1|1].lmax);
}
void build(int k,int l,int r){
if(l==r){
t[k].max=t[k].sum=t[k].lmax=t[k].rmax=a[l];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
node query(int k,int l,int r,int x,int y){
if(x<=l&&r<=y){
return t[k];
}
int mid=(l+r)>>1;
if(y<=mid) return query(k<<1,l,mid,x,y);
else if(x>mid) return query(k<<1|1,mid+1,r,x,y);
else{
node a=query(k<<1,l,mid,x,y),b=query(k<<1|1,mid+1,r,x,y);
node tmp;
tmp.sum=a.sum+b.sum;
tmp.lmax=max(a.lmax,a.sum+b.lmax);
tmp.rmax=max(b.rmax,b.sum+a.rmax);
tmp.max=maxx(a.max,b.max,a.rmax+b.lmax);
return tmp;
}
}
void update(int k,int l,int r,int x,int v){
if(l==r){
t[k].max=t[k].lmax=t[k].rmax=t[k].sum=v;
return;
}
int mid=(l+r)>>1;
if(x<=mid) update(k<<1,l,mid,x,v);
if(x>mid) update(k<<1|1,mid+1,r,x,v);
pushup(k);
}
int main(){
n=read(); m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for(int i=1;i<=m;i++){
ll k=read(),a=read(),b=read();
if(k==1){
if(a>b) swap(a,b);
printf("%lld\n",query(1,1,n,a,b).max);
}
else{
update(1,1,n,a,b);
}
}
return 0;
}