这题可以说是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;
}