uva 3938 静态数组 动态最大连续和(线段树

线段树维护区间前缀和后缀和连续和最大(前两者自身递推配合前缀和数组,后者分解为自身和前两种结合情况)支持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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值