UvaLA 3938 "Ray, Pass me the dishes!"
| Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hungry. In return for Neal's help, Ray makes a great dinner for Neal. When it is time for dinner, Ray arranges all the dishes he makes in a single line (actually this line is very long ... <tex2html_verbatim_mark>, the dishes are represented by 1, 2, 3 ... <tex2html_verbatim_mark>). ``You make me work hard and don't pay me! You refuse to teach me Latin Dance! Now it is time for you to serve me", Neal says to himself.
Every dish has its own value represented by an integer whose absolute value is less than 1,000,000,000. Before having dinner, Neal is wondering about the total value of the dishes he will eat. So he raises many questions about the values of dishes he would have.
For each question Neal asks, he will first write down an interval [a, b] <tex2html_verbatim_mark>(inclusive) to represent all the dishes a, a + 1,..., b <tex2html_verbatim_mark>, where a <tex2html_verbatim_mark>and b <tex2html_verbatim_mark>are positive integers, and then asks Ray which sequence of consecutive dishes in the interval has the most total value. Now Ray needs your help.
Input
The input file contains multiple test cases. For each test case, there are two integers n <tex2html_verbatim_mark>and m <tex2html_verbatim_mark>in the first line (n, m < 500000) <tex2html_verbatim_mark>. n <tex2html_verbatim_mark>is the number of dishes and m <tex2html_verbatim_mark>is the number of questions Neal asks.
Then n <tex2html_verbatim_mark>numbers come in the second line, which are the values of the dishes from left to right. Next m <tex2html_verbatim_mark>lines are the questions and each line contains two numbers a <tex2html_verbatim_mark>, b <tex2html_verbatim_mark>as described above. Proceed to the end of the input file.
Output
For each test case, output m <tex2html_verbatim_mark>lines. Each line contains two numbers, indicating the beginning position and end position of the sequence. If there are multiple solutions, output the one with the smallest beginning position. If there are still multiple solutions then, just output the one with the smallest end position. Please output the result as in the Sample Output.
Sample Input
3 1
1 2 3
1 1
Sample Output
Case 1:
1 1
也叫UVA 1400.。。。。
给一个区间{a,b},求区间内最大的连续和的范围 i,j
非常麻烦的线段树,调了好长时间。。。。。
每个节点维护,最大前缀和的位置pref,最大后缀和的位置suff,以及最大连续和的区间范围sub。。。。
向上更新的时候,sub={两个子结点的sub,两个子结点交接处的和}
pref={左子结点的pref,延续到右子结点pref的和} suff也一样
查询的时候,i,j可能是子结点的sub,也可能是左右结点并出来的值。。。
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 typedef long long int LL;
typedef pair<int,int> Interval;
const int maxn=; LL pref_sum[maxn];
LL sum(int a,int b){return pref_sum[b]-pref_sum[a-];}
LL sum(Interval i){return sum(i.first,i.second);} Interval better(Interval a,Interval b)
{
LL A=sum(a),B=sum(b);
if(A==B)
{
if(a<b) return a; else return b;
}
else if(A>B) return a;
else if(A<B) return b;
} struct IntervalTree
{
LL max_pref[maxn<<],max_suff[maxn<<];
Interval max_sub[maxn<<];
///pushUP build query_suff query_pref query
void pushUP(int l,int r,int rt)
{
///sub
int lc=rt<<;
int rc=rt<<|;
max_sub[rt]=better(max_sub[lc],max_sub[rc]);
max_sub[rt]=better(max_sub[rt],make_pair(max_suff[lc],max_pref[rc])); ///prex
LL v1=sum(l,max_pref[lc]);
LL v2=sum(l,max_pref[rc]);
if(v1==v2)
max_pref[rt]=max_pref[lc];
else
max_pref[rt]=v1>v2?max_pref[lc]:max_pref[rc]; ///suffx
v1=sum(max_suff[rc],r);
v2=sum(max_suff[lc],r);
if(v1==v2)
max_suff[rt]=max_suff[lc];
else
max_suff[rt]=v1>v2?max_suff[rc]:max_suff[lc];
}
void build(int l,int r,int rt)
{
if(l==r)
{
max_suff[rt]=max_pref[rt]=l;
max_sub[rt]=make_pair(l,l);
return ;
}
int m=(l+r)>>;
build(lson);
build(rson);
pushUP(l,r,rt);
}
Interval query_pref(int L,int R,int l,int r,int rt)
{
if(max_pref[rt]<=R) return make_pair(L,max_pref[rt]);
int m=(l+r)>>;
if(m>=R) return query_pref(L,R,lson);
Interval i=query_pref(L,R,rson);
i.first=L;
return better(i,make_pair(L,max_pref[rt<<]));
}
Interval query_suff(int L,int R,int l,int r,int rt)
{
if(max_suff[rt]>=L) return make_pair(max_suff[rt],R);
int m=(l+r)>>;
if(m<L) return query_suff(L,R,rson);
Interval i=query_suff(L,R,lson);
i.second=R;
return better(i,make_pair(max_suff[rt<<|],R));
}
Interval query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return max_sub[rt];
int m=(l+r)>>;
if(R<=m) return query(L,R,lson);
if(L>m) return query(L,R,rson);
Interval i1=query_pref(L,R,rson);
Interval i2=query_suff(L,R,lson);
Interval i3=better(query(L,R,lson),query(L,R,rson));
return better(i3,make_pair(i2.first,i1.second));
}
}; IntervalTree tree; int main()
{
int cas=,a,b,n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
pref_sum[]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a);
pref_sum[i]=pref_sum[i-]+a;
}
tree.build(,n,);
printf("Case %d:\n",cas++);
while(m--)
{
scanf("%d%d",&a,&b);
Interval ans=tree.query(a,b,,n,);
printf("%d %d\n",ans.first,ans.second);
}
}
return ;
}
UvaLA 3938 "Ray, Pass me the dishes!"的更多相关文章
- uvalive 3938 "Ray, Pass me the dishes!" 线段树 区间合并
题意:求q次询问的静态区间连续最大和起始位置和终止位置 输出字典序最小的解. 思路:刘汝佳白书 每个节点维护三个值 pre, sub, suf 最大的前缀和, 连续和, 后缀和 然后这个题还要记录解的 ...
- UVALive 3938 - "Ray, Pass me the dishes!" - [最大连续子列和+线段树]
题目链接:https://cn.vjudge.net/problem/UVALive-3938 参考刘汝佳书上说的: 题意: 给出一个长度为n的序列, 再给出m个询问, 每个询问是在序列 $[a,b] ...
- UVALive 3938 Ray, Pass me the dishes! (动态最大连续和)
题意:求一个动态区间的最大连续和. 静态版本的O(n)算法显示不适用了,但是可以用线段树分治,因为一个连续和要在两边的区间,要么跨越两边,对于一个结点维护最大前缀和,后缀和,子区间连续和. 题目要求输 ...
- UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)
"Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...
- UVA 1400 1400 - "Ray, Pass me the dishes!"(线段树)
UVA 1400 - "Ray, Pass me the dishes!" option=com_onlinejudge&Itemid=8&page=show_pr ...
- 【LA3938】"Ray, Pass me the dishes!"
原题链接 Description After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hun ...
- UVALive - 3938:"Ray, Pass me the dishes!"
优美的线段树 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring& ...
- 线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"
题目传送门 题意:动态最大连续子序列和,静态的题目 分析:nlogn的归并思想.线段树维护结点的三个信息,最大前缀和,最大后缀和,该区间的最大和的两个端点,然后答案是三个的better.书上用pair ...
- UVa 1400 (线段树) "Ray, Pass me the dishes!"
求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...
随机推荐
- Linux多线程编程
线程和进程的区别是: 进程是拷贝主进程的数据段和代码段的. 线程是和主进程公用一份数据段和代码段的. 线程一旦创建,就从指定的入口函数开始执行. 相关头文件: #include <pthread ...
- hadoopfs: 未找到命令...
https://zhidao.baidu.com/question/240817305095236244.html 学习hadoop测试http://blog.csdn.net/thinkpadshi ...
- 使用Minicom基于串口调试HiKey
虽然通过adb shell调试方便,但是有些时候不得不借助于串口进行调试,比如测试suspend to ram之类的功能时,adb服务被关闭. 同时在minicom中也可以进入shell,进行操作. ...
- Javascript身份证号码验证
"来来来,坐这儿". "什么?我可是有身份的人,怎么能和你坐一块儿".沛笠晃了晃手里的身份证,不屑说道. "你咋不上天呢?有身份还喝油条吃豆浆&quo ...
- NFS简单使用
NFS网络文件系统(Network File System),由Sun公司开发,从名字上就能够知道这个服务是通过网络的方式来共享文件系统,目前RHEL 6上使用的版本为NFSv4,提供有状态的连接,追 ...
- 表单验证插件之jquery.validate.js
提到表单验证的插件,第一个想到的就是jquery.validate.js,所以小生想在这里稍微详细地说一下这款插件的具体使用方法,便于理解,我直接附上整段demo的代码(没怎么调样式,主要是看js): ...
- [转]Android自定义控件三部曲系列完全解析(动画, 绘图, 自定义View)
来源:http://blog.csdn.net/harvic880925/article/details/50995268 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)—— ...
- 使用plsql创建表空间和用户
使用plsql创建oracle数据库的表空间和用户,并授权的语句.1.创建表空间:说明:datafile是指定创建位置,指向oracle数据库的默认位置:autoextend 设置容量为自动增长,50 ...
- COGS 2533. [HZOI 2016]小鱼之美
我们可以发现所有的操作当中,只有坐标的增加,没有坐标的减少. 所以我们可以发现这么一个简单的事实,一条鱼一旦出了渔网,那么它就不可能再回来. 但是目前这并没有什么卵用. 我们可以把询问一个矩阵当中的鱼 ...
- CSS实现文字省略
1.首先给用于放文本的标签元素设置一个宽度值,并设置溢出属性overflow为溢出隐藏. width: 245px;/*一定要设置固定宽度*/ overflow: hidden;/*不显示超过对象尺寸 ...