题目链接

https://www.luogu.org/problemnew/show/P4314

https://www.lydsy.com/JudgeOnline/problem.php?id=3064

分析

其实我是在看吉司机线段树课件时看到这题很感兴趣就跑过来做

显然如果数据小一点可以用分块什么的比较好搞

但是这个数据范围可能用\(log N\)的数据结构更舒服一点

怎么搞呢?请阅读国家集训队2016论文集之《区间最值操作与历史最值问题——杭州学军中学 吉如一》,对,就是我们敬爱可亲的吉司机.

看不懂?实际上就是告诉我们维护6个\(lazy\)_\(tag\):

  1. \(nmx\)表示当前区间最大值,\(add\)表示当前区间加法标记,\(set\)表示当前区间赋值标记

  2. \(pmx\)表示当前区间历史最大值,\(padd\)表示当前区间在下传此标记前时历史最大加法标记,\(pset\)表示当前区间在下传此标记前历史最大赋值标记

这样\(lazy\)_\(tag\)之间的合并就比较显然了

然后再结合论文食用,或是看代码理解一下

当然GXZlegend大佬使用吉司机的另一个方法也是可行的

http://www.cnblogs.com/GXZlegend/p/8315275.html

注意

我查错又查了一个小时

  • 注意不要把\(-inf\)写成\(inf\)

  • 在\(pushdown\)时思维一定要清晰,注意是哪些标记会对其他标记产生影响

代码

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cctype>
  6. #include <iostream>
  7. #define ll long long
  8. #define ri register int
  9. using std::max;
  10. const int inf=0x3f3f3f3f;
  11. const int maxn=100005;
  12. template <class T>inline void read(T &x){
  13. x=0;int ne=0;char c;
  14. while(!isdigit(c=getchar()))ne=c=='-';
  15. x=c-48;
  16. while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
  17. x=ne?-x:x;return ;
  18. }
  19. int n;
  20. int nmx[maxn<<2],add[maxn<<2],set[maxn<<2];
  21. int pmx[maxn<<2],padd[maxn<<2],pset[maxn<<2];
  22. int num[maxn];
  23. int L,R,dta;
  24. void build(int now,int l,int r){
  25. set[now]=nmx[now]=pmx[now]=pset[now]=-inf;
  26. padd[now]=add[now]=0;
  27. if(l==r){
  28. nmx[now]=pmx[now]=num[l];
  29. return ;
  30. }
  31. int mid=(l+r)>>1;
  32. build(now<<1,l,mid);
  33. build(now<<1|1,mid+1,r);
  34. nmx[now]=pmx[now]=max(nmx[now<<1],nmx[now<<1|1]);
  35. return ;
  36. }
  37. inline void pushdown(int now){
  38. if(padd[now]){
  39. pmx[now<<1]=max(pmx[now<<1],nmx[now<<1]+padd[now]);
  40. if(set[now<<1]!=-inf)
  41. pset[now<<1]=max(pset[now<<1],set[now<<1]+padd[now]);
  42. else
  43. padd[now<<1]=max(padd[now<<1],add[now<<1]+padd[now]);
  44. pmx[now<<1|1]=max(pmx[now<<1|1],nmx[now<<1|1]+padd[now]);
  45. if(set[now<<1|1]!=-inf)
  46. pset[now<<1|1]=max(pset[now<<1|1],set[now<<1|1]+padd[now]);
  47. else
  48. padd[now<<1|1]=max(padd[now<<1|1],add[now<<1|1]+padd[now]);
  49. padd[now]=0;
  50. }
  51. if(pset[now]!=-inf){
  52. pmx[now<<1]=max(pmx[now<<1],pset[now]);
  53. pset[now<<1]=max(pset[now<<1],pset[now]);
  54. pmx[now<<1|1]=max(pmx[now<<1|1],pset[now]);
  55. pset[now<<1|1]=max(pset[now<<1|1],pset[now]);
  56. pset[now]=-inf;
  57. }
  58. if(add[now]){
  59. nmx[now<<1]+=add[now];
  60. pmx[now<<1]=max(pmx[now<<1],nmx[now<<1]);
  61. if(set[now<<1]!=-inf){
  62. set[now<<1]+=add[now];
  63. pset[now<<1]=max(pset[now<<1],set[now<<1]);
  64. }
  65. else {
  66. add[now<<1]+=add[now];
  67. padd[now<<1]=max(padd[now<<1],add[now<<1]);
  68. }
  69. nmx[now<<1|1]+=add[now];
  70. pmx[now<<1|1]=max(pmx[now<<1|1],nmx[now<<1|1]);
  71. if(set[now<<1|1]!=-inf){
  72. set[now<<1|1]+=add[now];
  73. pset[now<<1|1]=max(pset[now<<1|1],set[now<<1|1]);
  74. }
  75. else {
  76. add[now<<1|1]+=add[now];
  77. padd[now<<1|1]=max(padd[now<<1|1],add[now<<1|1]);
  78. }
  79. add[now]=0;
  80. }
  81. if(set[now]!=-inf){
  82. nmx[now<<1]=set[now];
  83. pmx[now<<1]=max(pmx[now<<1],nmx[now<<1]);
  84. set[now<<1]=set[now];
  85. pset[now<<1]=max(pset[now<<1],set[now<<1]);
  86. nmx[now<<1|1]=set[now];
  87. pmx[now<<1|1]=max(pmx[now<<1|1],nmx[now<<1|1]);
  88. set[now<<1|1]=set[now];
  89. pset[now<<1|1]=max(pset[now<<1|1],set[now<<1|1]);
  90. set[now]=-inf;
  91. add[now<<1]=add[now<<1|1]=0;
  92. }
  93. return ;
  94. }
  95. void update_add(int now,int l,int r){
  96. if(L<=l&&r<=R){
  97. nmx[now]+=dta;
  98. pmx[now]=max(pmx[now],nmx[now]);
  99. if(set[now]!=-inf){
  100. set[now]+=dta;
  101. pset[now]=max(pset[now],set[now]);
  102. }
  103. else{
  104. add[now]+=dta;
  105. padd[now]=max(padd[now],add[now]);
  106. }
  107. return ;
  108. }
  109. int mid=(l+r)>>1;
  110. pushdown(now);
  111. if(L<=mid)update_add(now<<1,l,mid);
  112. if(mid<R)update_add(now<<1|1,mid+1,r);
  113. nmx[now]=max(nmx[now<<1],nmx[now<<1|1]);
  114. pmx[now]=max(pmx[now<<1],pmx[now<<1|1]);
  115. return ;
  116. }
  117. void update_set(int now,int l,int r){
  118. if(L<=l&&r<=R){
  119. nmx[now]=dta;
  120. pmx[now]=max(pmx[now],dta);
  121. set[now]=dta;
  122. pset[now]=max(pset[now],dta);
  123. add[now]=0;
  124. return ;
  125. }
  126. int mid=(l+r)>>1;
  127. pushdown(now);
  128. if(L<=mid)update_set(now<<1,l,mid);
  129. if(mid<R)update_set(now<<1|1,mid+1,r);
  130. nmx[now]=max(nmx[now<<1],nmx[now<<1|1]);
  131. pmx[now]=max(pmx[now<<1],pmx[now<<1|1]);
  132. return;
  133. }
  134. int query_now(int now,int l,int r){
  135. if(L<=l&&r<=R){
  136. return nmx[now];
  137. }
  138. int ans=-inf,mid=(l+r)>>1;
  139. pushdown(now);
  140. if(L<=mid)ans=max(ans,query_now(now<<1,l,mid));
  141. if(mid<R)ans=max(ans,query_now(now<<1|1,mid+1,r));
  142. nmx[now]=max(nmx[now<<1],nmx[now<<1|1]);
  143. pmx[now]=max(pmx[now<<1],pmx[now<<1|1]);
  144. return ans;
  145. }
  146. int query_history(int now,int l,int r){
  147. if(L<=l&&r<=R){
  148. return pmx[now];
  149. }
  150. int ans=-inf,mid=(l+r)>>1;
  151. pushdown(now);
  152. if(L<=mid)ans=max(ans,query_history(now<<1,l,mid));
  153. if(mid<R)ans=max(ans,query_history(now<<1|1,mid+1,r));
  154. nmx[now]=max(nmx[now<<1],nmx[now<<1|1]);
  155. pmx[now]=max(pmx[now<<1],pmx[now<<1|1]);
  156. return ans;
  157. }
  158. int q;
  159. int main(){
  160. int x,y,z;
  161. char opt[5];
  162. read(n);
  163. for(ri i=1;i<=n;i++)read(num[i]);
  164. build(1,1,n);
  165. read(q);
  166. while(q--){
  167. scanf("%s",opt);
  168. read(x),read(y);
  169. L=x,R=y;
  170. if(opt[0]=='Q'){
  171. printf("%d\n",query_now(1,1,n));
  172. }
  173. else if(opt[0]=='A'){
  174. printf("%d\n",query_history(1,1,n));
  175. }
  176. else if(opt[0]=='P'){
  177. read(dta);
  178. update_add(1,1,n);
  179. }
  180. else{
  181. read(dta);
  182. update_set(1,1,n);
  183. }
  184. }
  185. return 0;
  186. }

目前洛谷rank 2,在BZOJ上被吊打

洛谷题解P4314CPU监控--线段树的更多相关文章

  1. 题解——洛谷P2781 传教(线段树)

    可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\(  n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...

  2. 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  3. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

  4. 洛谷P4428二进制 [BJOI2018] 线段树

    正解:线段树 解题报告: 传送门! 话说开始看到这题的时候我想得hin简单 因为关于%3有个性质就是说一个数的各个位数之和%3=这个数%3嘛,小学基础知识? 我就想着,就直接建一棵树,只是这棵树要用个 ...

  5. BZOJ2141&洛谷1975 排队 【线段树套treap】

    题目 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别,排 ...

  6. 洛谷P3707 [SDOI2017]相关分析(线段树)

    题目描述 Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个 ...

  7. 【洛谷P2894】Hotel 线段树+二分查询

    题目大意:给定一个长度为 N 的序列,每个点有两种状态 1/0,表示占有和空闲,现支持 first-fit 查询是否有一段连续的长度为 X 的空闲子序列和区间赋值操作. 题解:get到了线段树新技能. ...

  8. 洛谷$P2486\ [SDOI2011]$染色 线段树+树链剖分

    正解:线段树+树链剖分 解题报告: 传送门$QwQ$ 其实是道蛮板子的题,,,但因为我写得很呆然后写了贼久之后发现想法有问题要重构,就很难受,就先写个题解算了$kk$ 考虑先跑个树剖,然后按$dfn$ ...

  9. 洛谷$P1712\ [NOI2016]$区间 线段树

    正解:线段树 解题报告: 传送门$QwQ$ $umm$很久以前做的了来补个题解$QwQ$ 考虑给每个区间按权值($r-l$从大往小排序,依次加入,然后考虑如果有一个位置被覆盖次数等于$m$了就可以把权 ...

随机推荐

  1. Thinkphp5 的sesssion在同一个控制器不同的方法无法获取session的原因和对策

    这一段在用thinkPHP5开发微信小程序接口的时候,在同一个控制器一个方法中存入session,在另一个方法中取出session,一直都是无法取出. 查阅各种资料得到原因:thinkPHP5里面的s ...

  2. 异步发送表单数据到JavaBean,并响应JSON文本返回

    1)  提交表单后,将JavaBean信息以JSON文本形式返回到浏览器 <form> 编号:<input type="text" name="id&q ...

  3. layui上传文件前加入确认提示

    //上传文件 upload: function () { layui.use('upload', function () { var upload = layui.upload; //执行实例 var ...

  4. intellij import包 顺序调整

    intellij中自动import的包顺序与eclipse不太一致,可以参照以下方式进行调整: eclipse中(笔者用的是eclipse luna)导入包的顺序依次是: javajavaxorgco ...

  5. Kafka API使用

  6. MATLAB学习(六)绘图图形功能

    >> x=0:.1:2*pi;plot(x,sin(x),x,cos(x))                               >> plot(x,sin(x),'p ...

  7. vagrant虚拟机共享目录在windows宿主下的禁忌

    问题背景 宿主环境:Windows10 开发环境:vagrant(ubuntu) 操作目录:synced_folder (共享目录 ) 执行命令:npm install 错误信息: npm ERR! ...

  8. Git(4):远程仓库

    添加\连接远程库 目前我们使用到的 Git 命令都是在本地执行,如果你想通过 Git 分享你的代码或者与其他开发人员合作. 你就需要将数据放到一台其他开发人员能够连接的服务器上. 远程仓库可以是Git ...

  9. JavaScript高程第三版笔记-DOM扩展

    在那个刀耕火种的年代,用过jQuery的都体会到了jQuery带来的便捷,尤其是元素选择器. jQuery(www.jquery.com)的核心就是通过 CSS 选择符查询 DOM 文档取得元素的引用 ...

  10. kubernetes/dashboard Getting Started

    Kubernetes Dashboard is a general purpose, web-based UI for Kubernetes clusters. It allows users to ...