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
- Live archive 3938 "Ray,Pass me the Dishes"
- UVALive 3938 "Ray, Pass me the dishes!"
- LA 3938 "Ray, Pass me the dishes!"
- UVALive - 3938 "Ray, Pass me the dishes!"
- UVa 3938 "Ray, Pass me the dishes!"
- 3938-Ray, Pass me the dishes!
- UVALive 3938 "Ray, Pass me the dishes!"
- LA 3938 "Ray, Pass me the dishes!"
- Regionals 2007 >> Asia - Nanjing - "Ray, Pass me the dishes!" 线段树 难 uva live 3938
- UVA live 3938 - "Ray, Pass me the dishes!"(线段树)
- LA 3938 - "Ray, Pass me the dishes!"(线段树)
- LA-3938-"Ray, Pass me the dishes!" 解题报告
- UvaLA 3938 "Ray, Pass me the dishes!"
- UVALive - 3938 "Ray, Pass me the dishes!" 线段树
- UVALive - 3938 "Ray, Pass me the dishes!" (线段树)
- uvalive 3938 Ray, Pass me the dishes!(线段树)
- UVa-1400 - "Ray, Pass me the dishes!"
- 1400 - "Ray, Pass me the dishes!"
- OC-分类、扩展、ARC
- 无向图最小环 hdu1599 (find the mincost route)
- MFC学习日记之常用控件
- sd卡、U盘作为启动盘后容量变小处理方法
- uva 1371 dp+二分
- Live archive 3938 "Ray,Pass me the Dishes"
- UVALive 6811 Irrigation Lines(匈牙利算法)
- poj1160 Post Office 四边形不等式优化
- 移动硬盘遇到无法访问,参数错误的处理方法
- 在jQuery中动态创建id,如何使用该Id来访问这个元素
- 送给所有还有梦想的人。
- static关键字2222222222222222222
- 【杭电oj5253】连接的管道
- CXF 发布WebService