LA 3938 "Ray, Pass me the dishes!"

来源:互联网 发布:win10开机速度优化 编辑:程序博客网 时间:2024/06/10 11:37

        这题写的比较蛋疼,看着刘汝佳大神的书写的,还写了一天,真是惭愧啊,思路和书上当然是一样的,维护最大连续和的区间、最大前缀和的区间以及最大后缀和的区间就行了,但是感觉不太好写,之前写完了敲了很多测试数据也没看出错误,wa了好几次,后来实在没办法,又重头到尾扫了几遍,改了几个bug才终于A掉了。

 

#include <iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=500010<<1;const int maxm=500000+10;ll sum[maxm];int maxsubx[maxn<<1],maxsuby[maxn<<1],maxprefix[maxn<<1],maxsuffix[maxn<<1];void PushUp(int l,int r,int rt){    int m=(l+r)>>1;    ll maxsum=sum[maxsuby[rt<<1]]-sum[maxsubx[rt<<1]-1];    maxsubx[rt]=maxsubx[rt<<1];    maxsuby[rt]=maxsuby[rt<<1];    if(maxsum<sum[maxprefix[rt<<1|1]]-sum[maxsuffix[rt<<1]-1])    {        maxsum=sum[maxprefix[rt<<1|1]]-sum[maxsuffix[rt<<1]-1];        maxsubx[rt]=maxsuffix[rt<<1];        maxsuby[rt]=maxprefix[rt<<1|1];    }    if(maxsum<sum[maxsuby[rt<<1|1]]-sum[maxsubx[rt<<1|1]-1])    {        maxsum=sum[maxsuby[rt<<1|1]]-sum[maxsubx[rt<<1|1]-1];        maxsubx[rt]=maxsubx[rt<<1|1];        maxsuby[rt]=maxsuby[rt<<1|1];    }    maxsum=sum[maxprefix[rt<<1]]-sum[l-1];    maxprefix[rt]=maxprefix[rt<<1];    if(maxsum<sum[maxprefix[rt<<1|1]]-sum[l-1])    {        maxsum=sum[maxprefix[rt<<1|1]]-sum[l-1];        maxprefix[rt]=maxprefix[rt<<1|1];    }    maxsum=sum[r]-sum[maxsuffix[rt<<1]-1];    maxsuffix[rt]=maxsuffix[rt<<1];    if(maxsum<sum[r]-sum[maxsuffix[rt<<1|1]-1])    {        maxsuffix[rt]=maxsuffix[rt<<1|1];    }    /*maxsum=sum[r]-sum[maxsuffix[rt<<1|1]-1];    //maxsuffix[rt]=maxsuffix[rt<<1|1];    if(maxsum<=sum[r]-sum[maxsuffix[rt<<1]-1])    {        maxsuffix[rt]=maxsuffix[rt<<1];    }*/}void build(int l,int r,int rt){    if(l==r)    {        maxsubx[rt]=maxsuby[rt]=l;        maxprefix[rt]=maxsuffix[rt]=l;        return;    }    int m=(l+r)>>1;    build(l,m,rt<<1);    build(m+1,r,rt<<1|1);    PushUp(l,r,rt);}void Query(int L,int R,int l,int r,int rt,int &x,int &y,int &pre,int &suf){    if(l>=L&&r<=R)    {        x=maxsubx[rt];        y=maxsuby[rt];        pre=maxprefix[rt];        suf=maxsuffix[rt];        return;    }    int xa,ya,xb,yb,pa,sa,pb,sb;    int m=(l+r)>>1;    if(m>=L&&m<R)    {        Query(L,R,l,m,rt<<1,xa,ya,pa,sa);        Query(L,R,m+1,r,rt<<1|1,xb,yb,pb,sb);        ll maxsum=sum[ya]-sum[xa-1];        x=xa;y=ya;        if(maxsum<sum[pb]-sum[sa-1])        {            maxsum=sum[pb]-sum[sa-1];            x=sa;            y=pb;        }        if(maxsum<sum[yb]-sum[xb-1])        {            maxsum=sum[yb]-sum[xb-1];            x=xb;            y=yb;        }        maxsum=sum[pa]-sum[L-1];        pre=pa;        if(maxsum<sum[pb]-sum[L-1])        {            pre=pb;        }        maxsum=sum[R]-sum[sa-1];        suf=sa;        if(maxsum<sum[R]-sum[sb-1])        {            suf=sb;        }        /*maxsum=sum[R]-sum[sb-1];        suf=sb;        if(maxsum<=sum[R]-sum[sa-1])        {            suf=sa;        }*/        return;    }    if(m>=L)    {        Query(L,R,l,m,rt<<1,xa,ya,pa,sa);        x=xa;        y=ya;        pre=pa;        suf=sa;    }    else if(m<R)    {        Query(L,R,m+1,r,rt<<1|1,xb,yb,pb,sb);        x=xb;        y=yb;        pre=pb;        suf=sb;    }}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n,m;    int tcase=0;    while(~scanf("%d%d",&n,&m))    {        tcase++;        sum[0]=0;        for(int i=1;i<=n;++i)        {            scanf("%lld",&sum[i]);            sum[i]+=sum[i-1];        }        build(1,n,1);        printf("Case %d:\n",tcase);        int l,r,x,y,p,s;        for(int i=0;i<m;++i)        {            scanf("%d%d",&l,&r);            Query(l,r,1,n,1,x,y,p,s);            printf("%d %d\n",x,y);        }    }    return 0;}