• UVA1400 "Ray, Pass me the dishes!"


    思路

    线段树维护最大子段和,只不过这题还要维护左右端点

    还是维护pre,suf,sum,ans,只不过每个再多出一个维护端点的变量即可

    注意多解讨论的大于号和大于等于号

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define int long long
    using namespace std;
    const int MAXN = 500100;
    struct Node{
        int premax,sufmax,preid,sufid,maxid,maxx,sum,maxxidl,maxxidr;
    }Seg[500100<<2];
    int a[500100],n,m;
    void pushup(Node &o,Node lson,Node rson){
        o.sum=lson.sum+rson.sum;
        if(lson.premax>=(lson.sum+rson.premax)){
            o.premax=lson.premax;
            o.preid=lson.preid;
        }
        else{
            o.premax=lson.sum+rson.premax;
            o.preid=rson.preid;
        }
        if(rson.sufmax>(rson.sum+lson.sufmax)){
            o.sufmax=rson.sufmax;
            o.sufid=rson.sufid;
        }
        else{
            o.sufmax=rson.sum+lson.sufmax;
            o.sufid=lson.sufid;
        }
        if(lson.maxx>=max(rson.maxx,lson.sufmax+rson.premax)){
            o.maxx=lson.maxx;
            o.maxxidl=lson.maxxidl;
            o.maxxidr=lson.maxxidr;
        }
        else{
            if(lson.sufmax+rson.premax>=rson.maxx){
                o.maxx=lson.sufmax+rson.premax;
                o.maxxidl=lson.sufid;
                o.maxxidr=rson.preid;
            }
            else{
                o.maxx=rson.maxx;
                o.maxxidl=rson.maxxidl;
                o.maxxidr=rson.maxxidr;
            }
        }
    }
    void build(int l,int r,int o){
        if(l==r){
            Seg[o].maxid=Seg[o].maxxidl=Seg[o].maxxidr=Seg[o].preid=Seg[o].sufid=l;
            Seg[o].maxx=Seg[o].premax=Seg[o].sufmax=Seg[o].sum=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,o<<1);
        build(mid+1,r,o<<1|1);
        pushup(Seg[o],Seg[o<<1],Seg[o<<1|1]);
    }
    Node query(int L,int R,int l,int r,int o){
        if(L<=l&&r<=R){
            return Seg[o];
        }
        int mid=(l+r)>>1;
        if(R<=mid)
            return query(L,R,l,mid,o<<1);
        else{
            if(L>mid)
                return query(L,R,mid+1,r,o<<1|1);
            else{
                Node ans;
                pushup(ans,query(L,R,l,mid,o<<1),query(L,R,mid+1,r,o<<1|1));
                return ans;
            }
        }
    }
    signed main(){
        int cnt=0;
        while(scanf("%lld %lld",&n,&m)==2){
            cnt++;
            memset(Seg,0,sizeof(Seg));
            for(int i=1;i<=n;i++)
                scanf("%lld",&a[i]);
            build(1,n,1);
            printf("Case %lld:
    ",cnt);
            for(int i=1;i<=m;i++){
                int l,r;
                scanf("%lld %lld",&l,&r);
                Node tmp=query(l,r,1,n,1);
                printf("%lld %lld
    ",tmp.maxxidl,tmp.maxxidr);
            }
        }   
        return 0;
    }
    
  • 相关阅读:
    SSM框架学习--Mybatis(一)入门
    Oracle 分页查询与数据去重
    JDBC基础
    Oracle 连接查询
    Java反射
    Oracle数据库常用SQL函数
    Oracle 中的SELECT 关键字(查询、检索)
    Python 短路机制
    Python 字符集
    SQL-MySQL
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10686047.html
Copyright © 2020-2023  润新知