原题链接

Description

After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hungry. In returnfor 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……, the dishes are represented by 1, 2, 3……). "You make me work hard and don't pay me! You refuse to teach me Latin Dance! Now it is timefor 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 rst write down an interval [a,b] (inclusive) to represent all

the dishes a,a+1,……,b, where a and b are positive integers, and then asks Ray which sequence ofconsecutive dishes in the interval has the most total value.

Now Ray needs your help

Input

he input le contains multiple test cases. For each test case, there are two integers n,m in the rst line (\(n,m < 500000\)).

n is the number of dishes and m is the number of questions Neal asks.

Then n numbers come in the second line, which are the values of the dishes from left to right. Next m lines are the questions and each line contains two numbers a,b as described above. Proceed to the end of the input .

Output

For each test case, output mlines. 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

1 1

Solution

显然,这是一个裸的区间内最大子段和问题,但是需要注意的是至少需要取一个数,并且多解输出区间尽可能靠左的。

首先讲一下解决最大子段和问题的思路:

维护三种信息:最大左子段和(意思是包含区间左端点的子段和)(记为lx),最大右子段和(记为rx),以及区间最大字段和(记为mx),然后线段树维护上述三种信息即可。

对于区间\([l,r]\) 我们可以按照如下方式维护信息:

$lx_{[l,r]}=max(lx_{[l,mid]},lx_{[mid+1,r]}+sum_{[l,mid]}) $

rx同理不多赘述

$mx_{[l,r]}=max(mx_{[l,mid]},mx_{[mid+1,r]},rx_{[l,mid]}+lx_{[mid+1,r]}) $

可以zkw线段树书写,时间效率\(O(m \log_{2} n)\)

Code

  1. #include <stdio.h>
  2. #define MN 500005
  3. #define M (1<<18)
  4. #define R register
  5. #define ll long long
  6. inline int read(){
  7. R int x; R char c; R bool f;
  8. for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
  9. for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
  10. return f?-x:x;
  11. }
  12. ll pre[MN],n,q,m;
  13. struct node{
  14. int l,r;
  15. node(int l=0,int r=0):l(l),r(r){};
  16. };
  17. inline ll sum(int l,int r){return pre[r]-pre[l-1];}
  18. inline ll sum(node &p){return sum(p.l,p.r);}
  19. inline bool operator >(node a,node b){return sum(a)>sum(b)||(sum(a)==sum(b)&&(a.l<b.l||(a.l==b.l&&a.r<b.r)));}
  20. inline node max(node a,node b){return a>b?a:b;}
  21. struct data{node l,r,m;bool p;data(node l,node r,node m):l(l),r(r),m(m){p=1;} data(){p=1;}};
  22. inline data operator +(data a,data b){
  23. if (!a.p) return b; if (!b.p) return a;
  24. R data c;c.l=max(a.l,node(a.l.l,b.l.r));
  25. c.r=max(b.r,node(a.r.l,b.r.r));
  26. c.m=max(max(a.m,b.m),node(a.r.l,b.l.r));return c;
  27. }
  28. data T[M<<1];
  29. inline data query(int l,int r){
  30. R data lans,rans;lans.p=0,rans.p=0;
  31. for (l+=m-1,r+=m+1; l^r^1; l>>=1,r>>=1){
  32. if (~l&1) lans=lans+T[l^1];
  33. if ( r&1) rans=T[r^1]+rans;
  34. }return lans+rans;
  35. }
  36. inline void work(){
  37. for (m=1; m<n+2; m<<=1);pre[0]=0;
  38. for (R int i=1; i<=n; ++i) pre[i]=pre[i-1]+read(),T[m+i]=data(node(i,i),node(i,i),node(i,i));
  39. for (R int i=n+m+1; i<=(m-1<<1); ++i) T[i].p=0;T[m].p=0;
  40. for (R int i=m-1; i; --i) T[i]=T[i<<1]+T[i<<1|1];
  41. for (R int i=1; i<=q; ++i){
  42. R int l=read(),r=read();
  43. R data ans=query(l,r);if (!ans.m.r) ans.m.r=ans.m.l;
  44. printf("%d %d\n",ans.m.l,ans.m.r);
  45. }
  46. }
  47. int main(){for (R int cnt=1; ~scanf("%d%d",&n,&q); ++cnt) printf("Case %d:\n",cnt),work();}

【LA3938】"Ray, Pass me the dishes!"的更多相关文章

  1. UvaLA 3938 "Ray, Pass me the dishes!"

                            "Ray, Pass me the dishes!" Time Limit: 3000MS   Memory Limit: Unkn ...

  2. UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...

  3. UVA 1400 1400 - &quot;Ray, Pass me the dishes!&quot;(线段树)

    UVA 1400 - "Ray, Pass me the dishes!" option=com_onlinejudge&Itemid=8&page=show_pr ...

  4. 【Unity3d】Ray射线初探-射线的原理及用法

    http://www.xiaobao1993.com/231.html 射线是一个无穷的线,开始于origin并沿着direction方向. 当射线碰到物体后.它就会停止发射. 在屏幕中拉一个CUBE ...

  5. UVALive3938 &quot;Ray, Pass me the dishes!&quot; 线段树动态区间最大和

    AC得相当辛苦的一道题.似乎不难,可是须要想细致, 開始的时候的错误思路----是受之前做过的区间最长连续子串影响http://blog.csdn.net/u011026968/article/det ...

  6. 线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"

    题目传送门 题意:动态最大连续子序列和,静态的题目 分析:nlogn的归并思想.线段树维护结点的三个信息,最大前缀和,最大后缀和,该区间的最大和的两个端点,然后答案是三个的better.书上用pair ...

  7. UVa 1400 (线段树) "Ray, Pass me the dishes!"

    求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...

  8. 1400 - "Ray, Pass me the dishes!"

    哈哈,原来题意看错了,但有多个解的时候,输出起点靠前的,如果起点一样,则输出终点靠前的,修改后AC的代码如下: #include <cstdio> #include <iostrea ...

  9. uvalive 3938 "Ray, Pass me the dishes!" 线段树 区间合并

    题意:求q次询问的静态区间连续最大和起始位置和终止位置 输出字典序最小的解. 思路:刘汝佳白书 每个节点维护三个值 pre, sub, suf 最大的前缀和, 连续和, 后缀和 然后这个题还要记录解的 ...

随机推荐

  1. SQLSERVER2012的分页新功能

    SQLSERVER2012的分页新功能 简介 SQL Server 2012中在Order By子句之后新增了OFFSET和FETCH子句来限制输出的行数从而达到了分页效果.相比较SQL Server ...

  2. 软件工程结对编程-2017282110264&2017282110249

    0 小组成员 李世钰 / 2017202110264 王成科 / 2017282110249 1 项目 GitHub 地址 && 演示地址 GitHub: https://github ...

  3. 原生ajax的请求函数

    ajax:一种请求数据的方式,不需要刷新整个页面:ajax的技术核心是 XMLHttpRequest 对象:ajax 请求过程:创建 XMLHttpRequest 对象.连接服务器.发送请求.接收响应 ...

  4. 第一篇:Python入门

    一.编程与编程语言 编程的目的: 计算机的发明,是为了用机器取代/解放人力,而编程的目的则是将人类的思想流程按照某种能够被计算机识别表达方式传递给计算机,从而达到让计算机能够像人脑/电脑一样自动执行的 ...

  5. C# 大数组赋值给小数组,小数组赋值给大数组

    ]; ]; " }; arraymax = arraystr;//变成和arraystr一样 arraymin = arraystr;//变成和arraystr一样

  6. Andrew Ng机器学习第一章——初识机器学习

    机器学习的定义 计算机程序从经验E中学习,解决某一任务T.进行某一性能度量P,通过P测定在T上的表现因E而提高. 简而言之:程序通过多次执行之后获得学习经验,利用这些经验可以使得程序的输出结果更为理想 ...

  7. windows系统设置虚拟机开机自启并运行虚拟系统

    简述 很多用windows系统电脑开发的童鞋,会在自己电脑上装一个虚拟机,然后在装一个linux系统当作服务器来使用. 但每次电脑开机都要去重启一下虚拟机电源,实在是不划算.下面博主教大家在windo ...

  8. SecureCRT安装

    第一步:下载SecureCRT&SecureCRT激活工具 首先下载SecureCRT安装包和SecureCRT激活工具,SecureCRT&SecureCRT激活工具下载地址:链接: ...

  9. SpringMVC(十):SpringMVC 处理输出模型数据之Map及Model

    Spring MVC提供了以下几种途径输出模型数据: 1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据: 2)Map及Model:处理方法 ...

  10. C#使用Socket实现一个socket服务器与多个socket客户端通信

    在分布式调度系统中,如果要实现调度服务器与多台计算节点服务器之间通信,采用socket来实现是一种实现方式,当然我们也可以通过数据存储任务,子节点来完成任务,但是往往使用数据作为任务存储都需要定制开发 ...