UVa 3938 "Ray, Pass me the dishes!"

来源:互联网 发布:unity3d vs2015 编辑:程序博客网 时间:2024/06/05 09:36

        题意:给一个长度为n的序列D,对m个询问做出回答。对于询问(a,b),需要找到两个下标x,y,使得a<=x<=y<=b,并且Dx~Dy的和尽量大。如果有多解,x应该尽量小,如果还有多解,y应该尽量小。

        思路:线段树。每个节点维护这些内容:区间和,区间的最大子段和,最大前后缀和,最大子段和以及它们的下标。查询直接返回一个区间节点,建树时的节点合并其实和查询时的节点合并是一样的。

        照着大白书写了这题,感觉思路大为开阔~


#include<cstdio>#include<iostream>#include<algorithm>#include<string.h>#include<math.h>using namespace std;#define maxn 500010#define ll long longstruct node{ll sum;ll max_sub;ll max_suffix;ll max_prefix;int subl,subr;int sl,pr;int l;int r;};node tree[maxn*4];int build_tree(int n,int l,int r){tree[n].l=l; tree[n].r=r;if(l==r){int t;scanf("%d",&t);tree[n].sum=tree[n].max_sub=tree[n].max_prefix=tree[n].max_suffix=t;tree[n].subl=tree[n].subr=tree[n].sl=tree[n].pr=l;}else{int mid=(l+r)/2;build_tree(n*2,l,mid);build_tree(n*2+1,mid+1,r);tree[n].sum=tree[n*2].sum+tree[n*2+1].sum;if(tree[n*2].sum+tree[n*2+1].max_prefix > tree[n*2].max_prefix){tree[n].max_prefix=tree[n*2].sum+tree[n*2+1].max_prefix;tree[n].pr=tree[n*2+1].pr;}else{tree[n].max_prefix=tree[n*2].max_prefix;tree[n].pr=tree[n*2].pr;}if(tree[n*2+1].max_suffix > tree[n*2+1].sum+tree[n*2].max_suffix ){tree[n].max_suffix = tree[n*2+1].max_suffix;tree[n].sl=tree[n*2+1].sl;}else{tree[n].max_suffix = tree[n*2+1].sum+tree[n*2].max_suffix;tree[n].sl=tree[n*2].sl;}ll tmp[3];tmp[0]=tree[n*2].max_sub; tmp[1]=tree[n*2].max_suffix+tree[n*2+1].max_prefix;tmp[2]=tree[n*2+1].max_sub;sort(tmp,tmp+3);tree[n].max_sub=tmp[2];if(tmp[2]==tree[n*2].max_sub){tree[n].subl=tree[n*2].subl;tree[n].subr=tree[n*2].subr;}else if(tmp[2]==tree[n*2].max_suffix+tree[n*2+1].max_prefix){tree[n].subl=tree[n*2].sl;tree[n].subr=tree[n*2+1].pr;}else{tree[n].subl=tree[n*2+1].subl;tree[n].subr=tree[n*2+1].subr;}}}node query(int n,int l,int r){node re;if(tree[n].l==l&&tree[n].r==r){re=tree[n];return re;}int mid=(tree[n].l+tree[n].r)/2;if(r<=mid){return query(n*2,l,r);}else{if(l>mid){return query(n*2+1,l,r);}else{node nl=query(n*2,l,mid);node nr=query(n*2+1,mid+1,r);if(nl.sum+nr.max_prefix > nl.max_prefix){re.max_prefix=nl.sum+nr.max_prefix;re.pr=nr.pr;}else{re.max_prefix=nl.max_prefix;re.pr=nl.pr;}if(nr.max_suffix > nr.sum+nl.max_suffix ){re.max_suffix = nr.max_suffix;re.sl=nr.sl;}else{re.max_suffix = nr.sum+nl.max_suffix;re.sl=nl.sl;}ll tmp[3];tmp[0]=nl.max_sub; tmp[1]=nl.max_suffix+nr.max_prefix;tmp[2]=nr.max_sub;sort(tmp,tmp+3);re.max_sub=tmp[2];if(tmp[2]==nl.max_sub){re.subl=nl.subl;re.subr=nl.subr;}else if(tmp[2]==nl.max_suffix+nr.max_prefix){re.subl=nl.sl;re.subr=nr.pr;}else{re.subl=nr.subl;re.subr=nr.subr;}return re;}}}int main(){int n,m;int cas=0;while(cin>>n>>m){cas++;build_tree(1,1,n);printf("Case %d:\n",cas);for(int i=1;i<=m;i++){int l,r;scanf("%d%d",&l,&r);node ans=query(1,l,r);printf("%d %d\n",ans.subl,ans.subr);}}return 0;}




0 0
原创粉丝点击