题目链接:https://vjudge.net/contest/146667#problem/C

题意:动态的求一个区间的最大连续和。

分析:

看上去可以RMQ去做,但是,当分成两个部分,原来的部分的解可能是跨越这两个区间的。原问题的解不能通过RMQ分成的两个部分的解而得到。

线段树:

线段树很早之前就有学习,那个时候只会套模板,而这个题目几乎就是线段树的一个理解应用。

就在刚刚之前提到的那个问题一样,可以利用线段树维护3个信息:

max_prefix(最大前缀和的标号)

max_suffix(最大后缀和的标号)

有了这两个信息,就可以跨区间找到丢失的信息了。

还有一个就是结果 max_sub(最大连续和的标号,其中是一个pair类型)

建树时:

建好左右子树后,递推max_prefix,max_suffix,这两个都不用跨区间,递推max_sub需要跨区间。

这里没有更新操作。

询问时:

同样分三种情况,左半边,右半边,跨区间。

跨区间这里,就用到了我们之前维护的最大前缀和标号,和最大后缀和标号。

那么如何得到最大前缀和标号,和最大后缀和标号呢?

同理:也是分区间查找,但是右半部分的左边的标号必须是L,左半部分简单一点,就是左孩子的最大前缀和的标号。

同理最大后缀和的标号。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int maxn = + ;
  6. const int maxnode = + ;
  7. typedef long long LL;
  8. typedef pair<int,int> Interval;
  9.  
  10. LL prefix_sum[maxn];
  11.  
  12. //求区间和
  13. LL sum(int L,int R) {
  14. return prefix_sum[R] - prefix_sum[L-];
  15. }
  16.  
  17. //求区间和
  18. LL sum(Interval p) {
  19. return sum(p.first,p.second);
  20. }
  21.  
  22. Interval better(Interval a,Interval b) {
  23. if(sum(a)!=sum(b)) return sum(a) > sum(b) ? a : b;
  24. return a<b? a:b;
  25. }
  26.  
  27. int qL,qR;
  28.  
  29. struct IntervalTree
  30. {
  31. int max_prefix[maxnode]; //最大前缀和对应的标号
  32. int max_suffix[maxnode]; //最大后缀和对应的标号
  33. Interval max_sub[maxnode]; //最大连续和对应的起点和终点
  34.  
  35. void build(int o,int L,int R)
  36. {
  37. if(L==R)
  38. {
  39. max_prefix[o] = max_suffix[o] = L;
  40. max_sub[o] = make_pair(L,L);
  41. }
  42. else
  43. {
  44. int M = L+(R-L)/;
  45. int lc = o*,rc = o*+;
  46. build(lc,L,M);
  47. build(rc,M+,R);
  48.  
  49. //递推最大前缀和
  50. LL v1 = sum(L,max_prefix[lc]);
  51. LL v2 = sum(L,max_prefix[rc]);
  52. if(v1==v2) max_prefix[o] = min(max_prefix[lc],max_prefix[rc]);
  53. else max_prefix[o] = v1 > v2 ? max_prefix[lc] : max_prefix[rc];
  54.  
  55. //递推最大后缀和
  56. v1 = sum(max_suffix[lc],R);
  57. v2 = sum(max_suffix[rc],R);
  58. if(v1==v2) max_suffix[o] = min(max_suffix[lc],max_suffix[rc]);
  59. else max_suffix[o] = v1 > v2 ? max_suffix[lc] : max_suffix[rc];
  60.  
  61. //递推最大连续和
  62. max_sub[o] = better(max_sub[lc],max_sub[rc]);
  63. max_sub[o] = better(max_sub[o],make_pair(max_suffix[lc],max_prefix[rc]));
  64. }
  65. }
  66.  
  67. //求最大前缀和的那个区间
  68. Interval query_prefix(int o,int L,int R)
  69. {
  70. if(max_prefix[o]<=qR) return make_pair(L,max_prefix[o]);
  71. int M = L + (R-L)/;
  72. int lc = o*,rc = o* + ;
  73. if(qR<=M) return query_prefix(lc,L,M);
  74. Interval i = query_prefix(rc,M+,R);
  75. i.first = L;
  76. return better(i,make_pair(L,max_prefix[lc]));
  77. }
  78.  
  79. Interval query_suffix(int o,int L,int R)
  80. {
  81. if(max_suffix[o]>=qL) return make_pair(max_suffix[o],R);
  82. int M = L + (R-L) /;
  83. int lc = o*,rc = o*+;
  84. if(qL>M) return query_suffix(rc,M+,R);
  85. Interval i = query_suffix(lc,L,M);
  86. i.second = R;
  87. return better(i,make_pair(max_suffix[rc],R));
  88.  
  89. }
  90.  
  91. Interval query(int o,int L,int R)
  92. {
  93. if(qL<=L&&R<=qR) return max_sub[o];
  94. int M = L + (R - L) /;
  95. int lc = o*,rc = o*+;
  96. if(qR<=M) return query(lc,L,M);
  97. if(qL>M) return query(rc,M+,R);
  98. Interval i1 = query_prefix(rc,M+,R);
  99. Interval i2 = query_suffix(lc,L,M);
  100. Interval i3 = better(query(lc,L,M),query(rc,M+,R)); //分开
  101. return better(make_pair(i2.first,i1.second),i3); //跨区间
  102. }
  103.  
  104. };
  105.  
  106. IntervalTree tree;
  107.  
  108. int main()
  109. {
  110. int n,q,a;
  111. int cases = ;
  112. while(scanf("%d%d",&n,&q)==)
  113. {
  114. prefix_sum[] = ;
  115. for(int i=; i<n; i++)
  116. {
  117. scanf("%d",&a);
  118. prefix_sum[i+] = prefix_sum[i] + a;
  119. }
  120. tree.build(,,n);
  121. printf("Case %d:\n",cases++);
  122.  
  123. while(q--) {
  124. int L,R;
  125. scanf("%d%d",&L,&R);
  126. qL = L;
  127. qR = R;
  128. Interval ans = tree.query(,,n);
  129. printf("%d %d\n",ans.first,ans.second);
  130. }
  131.  
  132. }
  133.  
  134. return ;
  135. }

LA 3938 动态最大连续和的更多相关文章

  1. LA 3938 动态最大连续和 线段树

    题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...

  2. LA 3938 动态最大连续和(线段树)

    https://vjudge.net/problem/UVALive-3938 题意:给出一个长度为n的整数序列D,你的任务是对m个询问作出回答.对于询问(a,b),需要找到两个下标x和y,使得a≤x ...

  3. LA 3938 动态最大连续区间 线段树

    思路很清晰,实现很繁琐.分析过程可以参考LRJ,自己的总结晚些放. #include <cstdio> #include <cstring> #include <algo ...

  4. UVALive 3938 Ray, Pass me the dishes! (动态最大连续和)

    题意:求一个动态区间的最大连续和. 静态版本的O(n)算法显示不适用了,但是可以用线段树分治,因为一个连续和要在两边的区间,要么跨越两边,对于一个结点维护最大前缀和,后缀和,子区间连续和. 题目要求输 ...

  5. 2018年1月 mybatis+ 动态sql连续日期

    2018-01-111 .   如何在项目中快速查找对应的mapper.xml文件 从Controller入手,使用(Ctrl+鼠标左键)找到Service调用的方法,再找到底层方法,就能找到对应ma ...

  6. la 3938(未完成)

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

  7. 一个动态库连续注册的windows脚本regsvr32

    cmd ->for %1 in (%windir%\system32\*.dll) do regsvr32.exe /s %1

  8. LA 3938

    After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hungry. In return fo ...

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

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

随机推荐

  1. 转 rac中并行 PARALLEL 的设置

    sample 1: rac中并 行的设置 https://blog.csdn.net/wll_1017/article/details/8285574 我们的生产库一般在节点一上的压力比较大,在节点二 ...

  2. Linux IPC 共享内存

    共享内存 共享内存(shared memory)是最简单的Linux进程间通信方式之一. 使用共享内存,不同进程可以对同一块内存进行读写. 由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不 ...

  3. http 协议的简单学习 虽然有点老但是 还不错

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  4. Spark机器学习库(MLlib)官方指南手册中文版

    中文https://blog.csdn.net/liulingyuan6/article/details/53582300 https://yq.aliyun.com/articles/608083 ...

  5. Android官方架构组件介绍之应用(四)

    讲一个项目常见的功能,友盟统计功能 例如一个项目有很多多modlue,每个里面modlue都有Activity,Activity需要友盟统一,Fragment也需要友盟统计.一般做法就是继承一个Bas ...

  6. HDU - 6208 The Dominator of Strings HDU - 6208 AC自动机 || 后缀自动机

    https://vjudge.net/problem/HDU-6208 首先可以知道最长那个串肯定是答案 然后,相当于用n - 1个模式串去匹配这个主串,看看有多少个能匹配. 普通kmp的话,每次都要 ...

  7. SharePreferences的用法

    1.创建 sharepreferences的方法: 首先创建该对象: 例如:(注意现在后面的模式7.0可以使用的只有 MODE_PRIVATE,其他全过时了 ) SharedPreferences s ...

  8. Sublime_text 3 安装 Package Control

    作者博文地址:https://www.cnblogs.com/liu-shuai/ 一.自动安装: 1.通过快捷键 ctrl+` 或者 View > Show Console 菜单打开控制台 2 ...

  9. express中connect-flash中间件的使用

    在学习node的时候,flash是困扰我最久的一个中间件,之前一直都没有很好的理解,这里做一个总结. 参考自:http://yunkus.com/connect-flash-usage/ 什么是fla ...

  10. 相同datatable合并