• uva1400 "Ray, Pass me the dishes!"


    这题可以说是spoj GSSI的拓展题了,它求的是给定区间的最大连续和的两个端点下标。

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4146

    AC Code
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define maxn 500005
    struct node{
        int l,r,ll,rr;
        long long lsum,rsum,maxsum;
    }setree[maxn<<2];
    long long sum[maxn]={
        0
    };
    int ansr,ansl;
    long long maxsum;
    void pushup(int rt,int l,int m,int r)
    {
        if(setree[rt<<1].lsum>=sum[m]-sum[l-1]+setree[rt<<1|1].lsum){
            setree[rt].ll=setree[rt<<1].ll;
            setree[rt].lsum=setree[rt<<1].lsum;
        }
        else{
            setree[rt].ll=setree[rt<<1|1].ll;
            setree[rt].lsum=sum[m]-sum[l-1]+setree[rt<<1|1].lsum;
        }
        if(setree[rt<<1|1].rsum>sum[r]-sum[m]+setree[rt<<1].rsum){
            setree[rt].rr=setree[rt<<1|1].rr;
            setree[rt].rsum=setree[rt<<1|1].rsum;
        }
        else{
            setree[rt].rr=setree[rt<<1].rr;
            setree[rt].rsum=sum[r]-sum[m]+setree[rt<<1].rsum;
        }
        if(setree[rt<<1].maxsum>=setree[rt<<1|1].maxsum){
            setree[rt].maxsum=setree[rt<<1].maxsum;
            setree[rt].l=setree[rt<<1].l;
            setree[rt].r=setree[rt<<1].r;
        }
        else{
            setree[rt].maxsum=setree[rt<<1|1].maxsum;
            setree[rt].l=setree[rt<<1|1].l;
            setree[rt].r=setree[rt<<1|1].r;
        }
        if(setree[rt].maxsum<setree[rt<<1].rsum+setree[rt<<1|1].lsum){
            setree[rt].l=setree[rt<<1].rr;
            setree[rt].r=setree[rt<<1|1].ll;
            setree[rt].maxsum=setree[rt<<1].rsum+setree[rt<<1|1].lsum;
        }
        else if(setree[rt].maxsum==setree[rt<<1].rsum+setree[rt<<1|1].lsum){
            if(setree[rt].l>setree[rt<<1].rr){
                setree[rt].l=setree[rt<<1].rr;
                setree[rt].r=setree[rt<<1|1].ll;
            }
            else if(setree[rt].l==setree[rt<<1].rr)
            setree[rt].r=min(setree[rt].r,setree[rt<<1|1].ll);
        }
    }
    void build(int l,int r,int rt)
    {
        if(l==r){
            setree[rt].l=setree[rt].r=r;
            setree[rt].ll=setree[rt].rr=r;
            scanf("%lld",&setree[rt].maxsum);
            setree[rt].lsum=setree[rt].rsum=setree[rt].maxsum;
            sum[l]=sum[l-1]+setree[rt].lsum;
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        pushup(rt,l,m,r);
    }
    long long queryr(int l,int r,int rt,int L,int R)
    {
        if(L==l&&r==R){
            ansl=setree[rt].rr;
            return setree[rt].rsum;
        }
        int m=(l+r)>>1;
        if(R<=m)
        return queryr(lson,L,R);
        else if(L>m)
        return queryr(rson,L,R);
        else{
            long long res1=queryr(rson,m+1,R);
            int tmp=ansl;
            long long res2=sum[R]-sum[m]+queryr(lson,L,m);
            if(res2<res1){
                ansl=tmp;
                return res1;
            }
            return res2;
        }
    }
    long long queryl(int l,int r,int rt,int L,int R)
    {
        if(L==l&&r==R){
            ansr=setree[rt].ll;
            return setree[rt].lsum;
        }
        int m=(l+r)>>1;
        if(R<=m)
        return queryl(lson,L,R);
        else if(L>m)
        return queryl(rson,L,R);
        else{
            long long res1=queryl(lson,L,m);
            int tmp=ansr;
            long long res2=sum[m]-sum[L-1]+queryl(rson,m+1,R);
            if(res1>=res2){
                ansr=tmp;
                return res1;
            }
            return res2;
        }
    }
    long long query(int l,int r,int rt,int L,int R)
    {
        if(L==l&&r==R){
            if(maxsum<setree[rt].maxsum){
                maxsum=setree[rt].maxsum;
                ansl=setree[rt].l;
                ansr=setree[rt].r;
            }
            return setree[rt].maxsum;
        }
        int m=(l+r)>>1;
        if(R<=m)
        return query(lson,L,R);
        else if(L>m)
        return query(rson,L,R);
        else{
            long long ans1=query(lson,L,m);
            long long ans2=query(rson,m+1,R);
            int tmpl=ansl,tmpr=ansr;
            long long rsum=queryr(lson,L,m);
            long long lsum=queryl(rson,m+1,R);
            if(maxsum>lsum+rsum){
                ansl=tmpl;
                ansr=tmpr;
                return max(ans1,ans2);
            }
            else if(maxsum==lsum+rsum){
                if(tmpl<ansl){
                    ansl=tmpl;
                    ansr=tmpr;
                }
                else if(tmpl==ansl);
                ansr=min(ansr,tmpr);
                return max(ans1,ans2);
            }
            else{
                maxsum=lsum+rsum;
                return lsum+rsum;
            }
        }
    }
    int main()
    {
        int n,m,cas=1;
        while(~scanf("%d%d",&n,&m)){
            build(1,n,1);
            printf("Case %d:\n",cas++);
            while(m--){
                int l,r;
                maxsum=-(long long)1e15;
                scanf("%d%d",&l,&r);
                query(1,n,1,l,r);
                printf("%d %d\n",ansl,ansr);
            }
        }
        return 0;
    }
  • 相关阅读:
    IE6BUG
    20个开发人员非常有用的Java功能代码
    越是方向不清楚的时候,认真地干无意义的事越是错
    危险的vc6.0
    pspcidtable 学习
    玩的起也要输的起 。。没什么,照样支持你。。
    给自己写个小计划
    windbg 命令
    我要去三清山国家公园。。。
    设计
  • 原文地址:https://www.cnblogs.com/kim888168/p/3066015.html
Copyright © 2020-2023  润新知