meaning of the title
Given n n n numbers, q operations, two operations: change ax to y, find the maximum subsection sum of [l,r].
n,m<=50000,-10000<=ai<=10000
Title Solution
The problem of interval is to use segment tree to maintain and consider how to merge intervals.
When we find the maximum subsection sum between two blocks, the maximum subsection and the maximum subsection of the large interval may be one of the two, or the splicing part of the middle two intervals, which is the largest part on the right side of the left interval and the largest part on the left side of the right interval.
So we also need to record the maximum subsection sum of the interval close to the left and right. Now consider maintaining the maximum subsection and lmax of the left. When the interval merges, the lmax of the large interval may be the lmax of the left interval, or the whole interval on the left plus the lmax of the right interval. rmax is the same.
When querying an interval, the structure can merge the information.
#include<cstdio> #include<cstring> using namespace std; #define ls rt<<1 #define rs rt<<1|1 #define ll long long const int maxn=50005; int n,m; int a[maxn]; struct cx{ ll sum,dat,lmax,rmax;// Interval sum,Maximum subsection sum of intervals,Maximum left subsegment sum,Maximum right subsegment sum }t[maxn<<2]; ll max(ll x,ll y){return x>y ? x : y ;} void get(cx &ret,cx lx,cx ry){ ret.sum=lx.sum+ry.sum; ret.lmax=max(lx.lmax,lx.sum+ry.lmax); ret.rmax=max(ry.rmax,ry.sum+lx.rmax); ret.dat=max(max(lx.dat,ry.dat),lx.rmax+ry.lmax); } void build(int rt,int l,int r){ if(l==r){ t[rt]=(cx){a[l],a[l],a[l],a[l]}; return ; } int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); get(t[rt],t[ls],t[rs]); } cx query(int rt,int l,int r,int a_l,int a_r){ //printf("%d %d %d %d \n",l,r,a_l,a_r); if(a_l<=l&&r<=a_r) return t[rt]; int mid=(l+r)>>1; if(a_r<=mid) return query(ls,l,mid,a_l,a_r); if(mid<a_l) return query(rs,mid+1,r,a_l,a_r); cx ret,x,y; x=query(ls,l,mid,a_l,a_r); y=query(rs,mid+1,r,a_l,a_r); get(ret,x,y); return ret; } void modify(int rt,int l,int r,int pos,int val){ if(l==r){ t[rt]=(cx){val,val,val,val}; return ; } int mid=(l+r)>>1; if(pos<=mid) modify(ls,l,mid,pos,val); else modify(rs,mid+1,r,pos,val); get(t[rt],t[ls],t[rs]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); scanf("%d",&m); for(int i=1;i<=m;i++){ int opt; scanf("%d",&opt); if(opt){ int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(1,1,n,l,r).dat); } else { int pos,val; scanf("%d%d",&pos,&val); modify(1,1,n,pos,val); } } }