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;
}
原文地址:https://www.cnblogs.com/dreagonm/p/10686047.html