题目链接:UOJ - 25

题目分析

每个操作就是将被操作的数限制在一个区间,比如 Set_Max(5) 就是将被操作的数限定在了 [5, INF] 的区间里。

这些操作是可加的,但是必须按照顺序,不满足交换律。

对每个节点维护两个标记 Min_Tag[x], Max_Tag[x] ,表示这个节点的数被限制在了 [Max_Tag, Min_Tag] 的区间内。

最终的答案应该是 gmax(Max_Tag[x], gmin(MinTag[x], Val[x]))。其中 Val[x] 是 x 这个位置的初值。

对某一个节点进行 Set_Max(Num) 时,就是进行这样的操作: Max_Tag[x] = gmax(Max_Tag[x], Num); Min_Tag[x] = gmax(Min_Tag[x], Num);

对某一个节点进行 Set_Min(Num) 时,就是进行这样的操作: Max_Tag[x] = gmin(Max_Tag[x], Num); Min_Tag[x] = gmin(Min_Tag[x], Num);

PushDown(x) 的时候就是用 x 的 Max_tag, Min_Tag 对 x 的孩子进行操作。

这样维护两个标记,最后取答案的时候再用 gmax(Max_Tag[x], gmin(MinTag[x], Val[x])) 取答案就行了,不过这道题中初值都是0。

代码

  1. #include "wall.h"
  2.  
  3. const int MaxN = 2000000 + 5, MaxH = 100000 + 5;
  4.  
  5. int Min_Tag[MaxN * 4], Max_Tag[MaxN * 4];
  6.  
  7. void Build(int x, int s, int t)
  8. {
  9. if (s == t)
  10. {
  11. Min_Tag[x] = MaxH;
  12. Max_Tag[x] = -MaxH;
  13. return;
  14. }
  15. Min_Tag[x] = MaxH;
  16. Max_Tag[x] = -MaxH;
  17. int m = (s + t) >> 1;
  18. Build(x << 1, s, m);
  19. Build(x << 1 | 1, m + 1, t);
  20. }
  21.  
  22. inline int gmin(int a, int b) {return a < b ? a : b;}
  23. inline int gmax(int a, int b) {return a > b ? a : b;}
  24.  
  25. inline void Paint_Max(int x, int Num)
  26. {
  27. Max_Tag[x] = gmax(Max_Tag[x], Num);
  28. Min_Tag[x] = gmax(Min_Tag[x], Num);
  29. }
  30.  
  31. inline void Paint_Min(int x, int Num)
  32. {
  33. Max_Tag[x] = gmin(Max_Tag[x], Num);
  34. Min_Tag[x] = gmin(Min_Tag[x], Num);
  35. }
  36.  
  37. inline void PushDown(int x)
  38. {
  39. Paint_Max(x << 1, Max_Tag[x]);
  40. Paint_Max(x << 1 | 1, Max_Tag[x]);
  41. Max_Tag[x] = -MaxH;
  42. Paint_Min(x << 1, Min_Tag[x]);
  43. Paint_Min(x << 1 | 1, Min_Tag[x]);
  44. Min_Tag[x] = MaxH;
  45. }
  46.  
  47. void Set_Max(int x, int s, int t, int l, int r, int Num)
  48. {
  49. if (l <= s && r >= t)
  50. {
  51. Paint_Max(x, Num);
  52. return;
  53. }
  54. PushDown(x);
  55. int m = (s + t) >> 1;
  56. if (l <= m) Set_Max(x << 1, s, m, l, r, Num);
  57. if (r >= m + 1) Set_Max(x << 1 | 1, m + 1, t, l, r, Num);
  58. }
  59.  
  60. void Set_Min(int x, int s, int t, int l, int r, int Num)
  61. {
  62. if (l <= s && r >= t)
  63. {
  64. Paint_Min(x, Num);
  65. return;
  66. }
  67. PushDown(x);
  68. int m = (s + t) >> 1;
  69. if (l <= m) Set_Min(x << 1, s, m, l, r, Num);
  70. if (r >= m + 1) Set_Min(x << 1 | 1, m + 1, t, l, r, Num);
  71. }
  72.  
  73. void Get_Ans(int x, int s, int t, int *&P)
  74. {
  75. if (s == t)
  76. {
  77. *P++ = gmax(Max_Tag[x], gmin(0, Min_Tag[x]));
  78. return;
  79. }
  80. PushDown(x);
  81. int m = (s + t) >> 1;
  82. Get_Ans(x << 1, s, m, P);
  83. Get_Ans(x << 1 | 1, m + 1, t, P);
  84. }
  85.  
  86. void buildWall(int n, int k, int op[], int left[], int right[], int height[], int finalHeight[])
  87. {
  88. Build(1, 1, n);
  89. for (int i = 0; i < k; ++i)
  90. {
  91. if (op[i] == 1) Set_Max(1, 1, n, left[i] + 1, right[i] + 1, height[i]);
  92. else Set_Min(1, 1, n, left[i] + 1, right[i] + 1, height[i]);
  93. }
  94. int *P = finalHeight;
  95. Get_Ans(1, 1, n, P);
  96. return;
  97. }

  

[UOJ 25] [IOI 2014] Wall 【线段树】的更多相关文章

  1. [UOJ UNR#1]奇怪的线段树

    来自FallDream的博客,未经允许,请勿转载, 谢谢. 原题可以到UOJ看,传送门 如果存在一个点是白的,却有儿子是黑的,显然无解. 不然的话,只要所有黑色的“黑叶子”节点,即没有黑色的儿子的节点 ...

  2. [UOJ#334][NOIP2017]列队 平衡树/线段树/树状数组

    题目链接 题意不说了,一辈子也忘不掉 解法1.平衡树 这题就是平衡树裸题,每一行开一棵维护前 \(m-1\) 个,最后一列单独维护,因为很多人没有用到,所以平衡树每个节点是一个区间(pair),分裂时 ...

  3. 2018.07.25 hdu5306Gorgeous Sequence(线段树)

    传送门 线段树基本操作. 要求维护区间取min" role="presentation" style="position: relative;"> ...

  4. UOJ#467. 【ZJOI2019】线段树 线段树,概率期望

    原文链接www.cnblogs.com/zhouzhendong/p/ZJOI2019Day1T2.html 前言 在LOJ交了一下我的代码,发现它比选手机快将近 4 倍. 题解 对于线段树上每一个节 ...

  5. UOJ#196. 【ZJOI2016】线段树 概率期望,动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ196.html 题解 先离散化,设离散化后的值域为 $[0,m]$ . 首先把问题转化一下,变成:对于每一个位置 $i$ ...

  6. uoj#228. 基础数据结构练习题(线段树区间开方)

    题目链接:http://uoj.ac/problem/228 代码:(先开个坑在这个地方) #include<bits/stdc++.h> using namespace std; ; l ...

  7. uoj #228. 基础数据结构练习题 线段树

    #228. 基础数据结构练习题 统计 描述 提交 自定义测试 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的 ...

  8. UOJ #228. 基础数据结构练习题 线段树 + 均摊分析 + 神题

    题目链接 一个数被开方 #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",st ...

  9. UOJ46 【清华集训2014】玄学 【时间线段树】

    题目链接:UOJ 这题的时间线段树非常的妙. 对时间建立线段树,修改的时候在后面加,每当填满一个节点之后就合并进它的父亲. 对于一个节点维护序列,发现这是一个分段函数,合并就是归并排序.于是就形成了差 ...

随机推荐

  1. JSP内置对象整理(转)

    ① out - javax.servlet.jsp.jspWriter out对象用于把结果输出到网页上. 方法: 1. void clear() ;清除输出缓冲区的内容,但是不输出到客户端. 2. ...

  2. Java线性表的排序

    Java线性表的排序 ——@梁WP 前言:刚才在弄JDBC的时候,忽然觉得order-by用太多了没新鲜感,我的第六感告诉我java有对线性表排序的封装,然后在eclipse里随便按了一下“.” ,哈 ...

  3. java: Eclipse jsp tomcat 环境搭建(完整)

    ] 欢迎您! 要学习一门语言,首先要做的就是搭建环境,然后能写一个小的Demo(类似Helloworld),不仅可以建立信心,而且还可以为之后的学习搭建一个验证平台,事半功倍. net领域的vs,号称 ...

  4. 如何写robots.txt?

    robin 发表在 八月 2, 2006 在国内,网站管理者似乎对robots.txt并没有引起多大重视,应一些朋友之请求,今天想通过这篇文章来简单谈一下robots.txt的写作. robots.t ...

  5. 最新的C#SqlHelper 类苏飞修改版(转载)

    /// <summary> /// 类说明:公共的数据库访问访问类 /// 编码日期:2010-4-22 /// 编 码 人:苏飞 /// 联系方式:361983679 Email:[ur ...

  6. 用Filezilla往ubuntu虚拟机上传文件

    也许不用这么复杂,但就这么干了 1.安卓ubuntu虚拟机 2.虚拟机安装ssh服务:sudo apt-get openssh-server 3.虚拟机新建目录test 4.修改test文件夹的访问权 ...

  7. 关于word-break,word-wrap换行

    目前项目中有一些流程日志需要动态显示到页面上,实现方法是ajax动态获取附加到<span></span>标签上,然后设置word-break:break-all样式使其自动换行 ...

  8. oracle redo日志维护

    环境 OS:Red Hat Linux As 5 DB:10.2.0.1 1.添加日志组 alter database add logfile group 4 ('/u01/app/oracle/or ...

  9. sql server抓取表结构的语句

    sql server 2008抓取方法: ---------------------------------------   SELECT      表名 = Case When A.colorder ...

  10. a*b(高进度乘以int类型的数)

    以下是我今日的a-b(高精度)的程序,\(^o^)/偶也偶也偶也偶也! 程序: #include<stdio.h> #include<string.h> char s[1000 ...