meaning of the title
Sequence single point modification, interval inquiry maximum continuous subsection sum.
Maximum subsections and hard to update, but the single point of modification here reduces the difficulty and does not need to maintain tags. What we need to do now is to support queries with maximum subsections by maintaining several data.
Considering that the maximum subsection sum is a continuous subsection, if you chop a knife in this subsection, it still has two segments:
In the left subsection, the largest subsection next to the right and In the right subsection, the largest subsection next to the left and
Conversely, if you know the maximum subparagraph sum close to the left in the right subparagraph and the maximum subparagraph and time close to the right in the left subparagraph, you can restore the maximum subparagraph. Of course, this is in the case of a known midpoint.
Because the largest subparagraph may also have no common part with the right subparagraph in the left subparagraph. So the answer is the sum of the largest subparagraph in the left subparagraph. On the contrary, the same is true.
As shown in the picture:
These three pieces of information can be used to piece together the largest subsection sum of the whole interval.
So four pieces of information are maintained: interval sum, maximum subsection sum, maximum subsection sum close to the left and maximum subsection sum close to the right.
The maximum subsection next to the left and the maximum subsection next to the right need to use the interval sum to update (O(1). This part is very good simulation, do not understand the code can be seen.
#include<iostream> #include<cstdio> using namespace std; const int MAXN=50005; int n,m,a[MAXN],sum[MAXN<<2],maxs[MAXN<<2],lefts[MAXN<<2],rights[MAXN<<2]; int u,v,w; struct data{ int _sum,_maxs,_lefts,_rights; }; inline void upd(int x) { sum[x]=sum[x<<1]+sum[x<<1|1]; maxs[x]=max(max(maxs[x<<1],maxs[x<<1|1]),rights[x<<1]+lefts[x<<1|1]); lefts[x]=max(sum[x<<1]+lefts[x<<1|1],lefts[x<<1]); rights[x]=max(rights[x<<1]+sum[x<<1|1],rights[x<<1|1]); } inline void build(int x,int l,int r) { int mid=(l+r)>>1; if(l==r) { sum[x]=a[l]; maxs[x]=a[l]; lefts[x]=a[l]; rights[x]=a[l]; return; } build(x<<1,l,mid); build(x<<1|1,mid+1,r); upd(x); } inline data query(int x,int l,int r,int ql,int qr) { int mid=(l+r)>>1; data temp,lt,rt; if(ql<=l&&r<=qr) { temp._sum=sum[x]; temp._maxs=maxs[x]; temp._lefts=lefts[x]; temp._rights=rights[x]; return temp; } if(ql<=mid) lt=query(x<<1,l,mid,ql,qr); if(mid<qr) rt=query(x<<1|1,mid+1,r,ql,qr); if(ql<=mid&&mid<qr) { temp._sum=lt._sum+rt._sum; temp._maxs=max(lt._rights+rt._lefts,max(lt._maxs,rt._maxs)); temp._lefts=max(lt._lefts,lt._sum+rt._lefts); temp._rights=max(rt._rights,lt._rights+rt._sum); return temp; } else { if(ql<=mid) return lt; else return rt; } } inline void modify(int x,int l,int r,int target,int num) { if(l==r&&r==target) { sum[x]=num; maxs[x]=num; lefts[x]=num; rights[x]=num; } else { int mid=(l+r)>>1; if(target<=mid) modify(x<<1,l,mid,target,num); if(mid<target) modify(x<<1|1,mid+1,r,target,num); upd(x); } } signed main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; build(1,1,n); cin>>m; for(register int i=1;i<=m;i++) { cin>>u>>v>>w; if(u==0) modify(1,1,n,v,w); if(u==1) cout<<query(1,1,n,v,w)._maxs<<"\n"; } return 0; }