Live archive 3938 "Ray,Pass me the Dishes"

来源:互联网 发布:管家婆sql下载 编辑:程序博客网 时间:2024/05/23 00:06

题意:给出一个长度为n的整数序列D,你的任务是对m个询问做出回答,对于询问(a,b),需要找到两个下标x,y使得a<=x<=y<=b并且使得Dx+Dx+1+……+Dy尽量大,如果有多组满足条件,应使x尽量小,如果还是有多解,y应该尽量小


这里要用线段树分治,一个连续和要么被包含在左儿子或者右儿子,要么跨越两个儿子,对于一个结点维护最大前缀和,后缀和,最大连续和。

题目要求输出区间,所以还要保存连续和最大的区间,以及前缀和,后缀和的位置。为了维护最大前缀和以及后缀和还需要一个区间和。

所以这道题写起来非常麻烦,但是思路还是 很清晰的


#include<cstdio>#include<iostream>#define ls (r<<1)#define rs ((r<<1)+1)#define LL long longusing namespace std;const int maxn=5e5+5;struct wk{    LL pre,suf,sub,sum;    int l,r,pr,sl;}tree[maxn<<2];int n,m,s[maxn];int x,y;inline void _read(int &x){    char t=getchar();bool sign=true;    while(t<'0'||t>'9')    {if(t=='-')sign=false;t=getchar();}    for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';    if(!sign)x=-x;}void updata(wk&u,wk&s1,wk&s2){    if(s1.pre>=s1.sum+s2.pre)u.pr=s1.pr,u.pre=s1.pre;else u.pr=s2.pr,u.pre=s1.sum+s2.pre;    if(s2.suf<=s2.sum+s1.suf)u.sl=s1.sl,u.suf=s2.sum+s1.suf;else u.sl=s2.sl,u.suf=s2.suf;    if(s1.sub>=s2.sub)u.l=s1.l,u.r=s1.r,u.sub=s1.sub;    else u.l=s2.l,u.r=s2.r,u.sub=s2.sub;    if(u.sub<s1.suf+s2.pre||(u.sub==s1.suf+s2.pre&&(u.l>s1.sl||(u.l==s1.sl&&u.r>s2.pr))))        u.sub=s1.suf+s2.pre,u.l=s1.sl,u.r=s2.pr;    u.sum=s1.sum+s2.sum;}void build(int r,int L,int R){    if(L==R){        wk& u=tree[r];        u.pre=u.suf=u.sub=u.sum=s[L];        u.l=u.r=u.pr=u.sl=L;        return;    }    int mid=(L+R)>>1;    build(ls,L,mid);    build(rs,mid+1,R);    updata(tree[r],tree[ls],tree[rs]);}wk find(int r,int L,int R){    if(x<=L&&R<=y)return tree[r];    int mid=(L+R)>>1;    wk ret;    if(x<=mid&&mid<y){    wk a=find(ls,L,mid);    wk b=find(rs,mid+1,R);        updata(ret,a,b);        return ret;    }    if(y<=mid)        return find(ls,L,mid);    return find(rs,mid+1,R);}int main(){    int kase=0;    while(scanf("%d%d",&n,&m)!=EOF){        for(int i=1;i<=n;i++)_read(s[i]);        build(1,1,n);        printf("Case %d:\n",++kase);        while(m--){_read(x);_read(y);            wk ans=find(1,1,n);            printf("%d %d\n",ans.l,ans.r);        }    }}


0 0