你若会这个题SCOI2018就有20分暴力。。。
维护整个区间和,左区间最大和,右区间最大和就完了。
#include<iostream>
#include<cstdio>
#define lc (p<<1)
#define rc (p<<1|1)
using namespace std;
const int N=5e5+1000;
inline int Max(int a,int b){
return a>b?a:b;
}
struct Node{
int l,r;
int lsum,rsum,sum,ssum;
}t[N*4];
int n,m;
int a[N];
void pushup(int p){
t[p].sum=t[lc].sum+t[rc].sum;
t[p].ssum=max(t[lc].ssum,max(t[rc].ssum,t[lc].rsum+t[rc].lsum));
t[p].lsum=max(t[lc].lsum,t[lc].sum+t[rc].lsum);
t[p].rsum=max(t[rc].rsum,t[rc].sum+t[lc].rsum);
}
void build(int a[],int p,int l,int r){
t[p].l=l;
t[p].r=r;
if(l==r){
int sum=0;
sum=a[l];
//cout<<l<<" "<<r<<endl;
t[p].lsum=sum;
t[p].rsum=sum;
t[p].ssum=sum;
t[p].sum=sum;
return;
}
int mid=(r+l)>>1;
build(a,lc,l,mid);
build(a,rc,mid+1,r);
pushup(p);
}
void update(int p,int k,int val){
if(t[p].l==t[p].r){
t[p].sum=val;
t[p].lsum=val;
t[p].rsum=val;
t[p].ssum=val;
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(k<=mid){
update(lc,k,val);
}
else{
update(rc,k,val);
}
pushup(p);
}
Node print(int p,int l,int r){
if(l <= t[p].l && r>=t[p].r){
return t[p];
}
int mmid = (t[p].l+t[p].r)>>1;
if(r<=mmid) return print(lc,l,r);
if(l>mmid) return print(rc,l,r);
Node temp1 =print(lc,l,mmid);
Node temp2 =print(rc,mmid+1,r);
temp1.ssum=Max(temp1.ssum,temp2.ssum);
temp1.ssum=Max(temp1.ssum,temp1.rsum+temp2.lsum);
temp1.lsum=Max(temp1.lsum,temp1.sum+temp2.lsum);
temp1.rsum=Max(temp2.rsum,temp2.sum+temp1.rsum);
temp1.sum+=temp2.sum;
return temp1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(a,1,1,n);
for(int i=1;i<=m;++i){
int x;
scanf("%d",&x);
if(x==2){
int pos,val;
scanf("%d%d",&pos,&val);
update(1,pos,val);
}
else{
int a,b;
scanf("%d%d",&a,&b);
if(a>b)swap(a,b);
Node ans=print(1,a,b);
printf("%d\n",ans.ssum);
}
}
return 0;
}