线段树维护区间前缀和后缀和连续和最大(前两者自身递推配合前缀和数组,后者分解为自身和前两种结合情况)支持nlogn插入logn查询目标
#include <bits/stdc++.h> #define lson l,m,i<<1 #define rson m+1,r,i<<1|1 using namespace std; typedef long long ll; const ll inf=1223372036854775807; struct node { ll v,l,r; node(){} node(ll a,ll b,ll c) { v=a,l=b,r=c; } bool operator < (const node b) const { if(v!=b.v) return v<b.v; if(l!=b.l) return l>b.l; return r>b.r; } }; const int N=500005+50; ll aa[N]; ll psum[N],ok; node sub[4*N],pre[4*N],suf[4*N]; void push_pre(int i,int l,int r) { int m=(l+r)>>1; node r1(psum[m]-psum[l-1]+pre[i<<1|1].v,l,pre[i<<1|1].r); pre[i]=max(r1,pre[i<<1]); } void push_suf(int i,int l,int r) { int m=(l+r)>>1; node r1(psum[r]-psum[m]+suf[i<<1].v,suf[i<<1].l,r); suf[i]=max(r1,suf[i<<1|1]); } void push_ans(int i,int l, int r) { node r1(suf[i<<1].v+pre[i<<1|1].v,suf[i<<1].l,pre[i<<1|1].r); r1=max(r1,sub[i<<1]); sub[i]=max(r1,sub[i<<1|1]); } void build(int l, int r, int i) { if(l==r) { sub[i].l=pre[i].l=suf[i].l=l; sub[i].r=pre[i].r=suf[i].r=r; sub[i].v=pre[i].v=suf[i].v=aa[++ok]; return ; } int m=(l+r)>>1; build(l,m,i<<1); build(m+1,r,i<<1|1); push_pre(i,l,r); push_suf(i,l,r); push_ans(i,l,r); } node query_pre(int ql,int qr,int l,int r,int i) { if(ql<=l&&r<=qr) { return pre[i]; } int m=(l+r)>>1; node r1(-inf,l,m),r2(-inf,m+1,r); if(qr<=m) return query_pre(ql,qr,lson); if(ql>m) return query_pre(ql,qr,rson); r1=query_pre(ql,qr,lson),r2=query_pre(ql,qr,rson); int ll=max(l,ql),rr=min(r,qr); node res (psum[m]-psum[ll-1]+r2.v,ll,r2.r); return max(res,r1); } node query_suf(int ql,int qr ,int l,int r,int i) { if(ql<=l&&r<=qr) { return suf[i]; } int m=(l+r)>>1; node r1(-inf,l,m),r2(-inf,m+1,r); if(qr<=m) return query_suf(ql,qr,lson); if(ql>m) return query_suf(ql,qr,rson); r1=query_suf(ql,qr,lson),r2=query_suf(ql,qr,rson); int ll=max(l,ql),rr=min(r,qr); node res (psum[rr]-psum[m]+r1.v,r1.l,rr); return max(res,r2); } node query_ans(int ql,int qr,int l,int r,int i) { if(ql<=l&&r<=qr) { return sub[i]; } int m=(l+r)>>1; node r1 (-inf,l,m),r2 (-inf,m+1,r); if(qr<=m) return query_ans(ql,qr,lson); if(ql>m) return query_ans(ql,qr,rson); r1=query_ans(ql,qr,lson),r2=query_ans(ql,qr,rson); node p1=query_suf(ql,qr,lson),p2=query_pre(ql,qr,rson); node res(p1.v+p2.v,p1.l,p2.r); return max(res,max(r1,r2)); } int main () { int cnt=1; int n,i,m; while(~scanf("%d%d",&n,&m)) { for(i=1;i<=n;++i) { scanf("%lld",&aa[i]); psum[i]=aa[i]+psum[i-1]; } ok=0; build(1,n,1); int l,r; printf("Case %d:\n",cnt++); for(i=1;i<=m;++i) { scanf("%d%d",&l,&r); node ans=query_ans(l,r,1,n,1); printf("%lld %lld\n",ans.l,ans.r); } } return 0; }