题目描述
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; }