题目描述
You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations:
modify the i-th element in the sequence or for given x y print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
输入输出格式
输入格式:
The first line of input contains an integer N. The following line contains N integers, representing the sequence A1..AN.
The third line contains an integer M. The next M lines contain the operations in following form:
0 x y: modify Ax into y (|y|<=10000).
1 x y: print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
输出格式:
For each query, print an integer as the problem required.
输入输出样例
6 4 -3
单点修改的最大子段和还是会的hhhh
每个节点维护四个值就行了。
注意查询的时候我们要用到当前区间左边的最大前缀。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define maxn 200005
using namespace std;
const int inf=1<<30;
int mx[maxn],mxl[maxn];
int mxr[maxn],ans,frontx;
int n,m,a[maxn],opt,le;
int ri,v,sum[maxn];
inline void pushup(int o,int lc,int rc){
sum[o]=sum[lc]+sum[rc];
mx[o]=max(mx[lc],max(mx[rc],mxl[rc]+mxr[lc]));
mxl[o]=max(mxl[lc],sum[lc]+mxl[rc]);
mxr[o]=max(mxr[rc],sum[rc]+mxr[lc]);
}
void build(int o,int l,int r){
if(l==r){
mxl[o]=mx[o]=mxr[o]=sum[o]=a[l];
return;
}
int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
build(lc,l,mid),build(rc,mid+1,r);
pushup(o,lc,rc);
}
void update(int o,int l,int r){
if(l==r){
mxl[o]=mx[o]=mxr[o]=sum[o]=v;
return;
}
int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
if(le<=mid) update(lc,l,mid);
else update(rc,mid+1,r);
pushup(o,lc,rc);
}
void query(int o,int l,int r){
if(l>=le&&r<=ri){
ans=max(ans,max(frontx+mxl[o],mx[o]));
frontx=max(frontx+sum[o],mxr[o]);
return;
}
int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
if(le<=mid) query(lc,l,mid);
if(ri>mid) query(rc,mid+1,r);
}
inline void req(){
ans=-inf,frontx=0;
query(1,1,n);
printf("%d\n",ans);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&opt,&le,&ri);
if(opt) req();
else{
v=ri;
update(1,1,n);
}
}
return 0;
}