题解

我们转而维护每个点的斜率,显然一个楼房能被看见它就是一个前缀最大值,斜率比较为了节约精度可以用向量替代

我们每个区间维护被看到的楼房的个数,和楼房的最大值,叶子节点在有楼房时,值为1

那么考虑合并两个区间,左节点的所有能被看到的楼房还是能被看到,右边节点能看到的楼房的斜率需要大于左边节点所需要的斜率最大值

为了找到这些我们去右节点的左右区间去找

如果这个值\(P\)大于等于区间左边的最大值,那么这个值要在右边找

如果小于的话,加上右边的大小,即\(tr[u].cnt - tr[u << 1].cnt\),然后递归到左边处理

复杂度\(O(n \log^2 n)\)

代码

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. #define pii pair<int,int>
  5. #define mp make_pair
  6. #define pb push_back
  7. #define enter putchar('\n')
  8. #define space putchar(' ')
  9. #define MAXN 100005
  10. //#define ivorysi
  11. using namespace std;
  12. typedef long long int64;
  13. typedef double db;
  14. template<class T>
  15. void read(T &res) {
  16. res = 0;char c = getchar();T f = 1;
  17. while(c < '0' || c > '9') {
  18. if(c == '-') f = -1;
  19. c = getchar();
  20. }
  21. while(c >= '0' && c <= '9') {
  22. res = res * 10 + c - '0';
  23. c = getchar();
  24. }
  25. res *= f;
  26. }
  27. template<class T>
  28. void out(T x) {
  29. if(x < 0) {x = -x;putchar('-');}
  30. if(x >= 10) {
  31. out(x / 10);
  32. }
  33. putchar('0' + x % 10);
  34. }
  35. struct Point {
  36. int64 x,y;
  37. Point(int64 _x = 0,int64 _y = 0) {
  38. x = _x;y = _y;
  39. }
  40. friend Point operator + (const Point &a,const Point &b) {
  41. return Point(a.x + b.x,a.y + b.y);
  42. }
  43. friend Point operator - (const Point &a,const Point &b) {
  44. return Point(a.x - b.x,a.y - b.y);
  45. }
  46. friend int64 operator * (const Point &a,const Point &b) {
  47. return a.x * b.y - a.y * b.x;
  48. }
  49. friend bool operator < (const Point &a,const Point &b) {
  50. return a * b > 0;
  51. }
  52. friend bool operator > (const Point &a,const Point &b) {
  53. return a * b < 0;
  54. }
  55. friend bool operator == (const Point &a,const Point &b) {
  56. return a * b == 0;
  57. }
  58. friend bool operator >= (const Point &a,const Point &b) {
  59. return a > b || a == b;
  60. }
  61. friend bool operator <= (const Point &a,const Point &b) {
  62. return a < b || a == b;
  63. }
  64. };
  65. struct node {
  66. int L,R,cnt;Point P;
  67. }tr[MAXN * 4];
  68. int N,M;
  69. void build(int u,int l,int r) {
  70. tr[u].L = l;tr[u].R = r;tr[u].cnt = 0;
  71. tr[u].P = Point(r,0);
  72. if(l == r) return;
  73. int mid = (l + r) >> 1;
  74. build(u << 1,l,mid);
  75. build(u << 1 | 1,mid + 1,r);
  76. }
  77. int Calc(int u,Point P) {
  78. if(tr[u].L == tr[u].R) return tr[u].P > P;
  79. if(P >= tr[u << 1].P) {
  80. return Calc(u << 1 | 1,P);
  81. }
  82. else {
  83. return Calc(u << 1,P) + tr[u].cnt - tr[u << 1].cnt;
  84. }
  85. }
  86. void Change(int u,int pos,int y) {
  87. if(tr[u].L == tr[u].R) {
  88. tr[u].P = Point(pos,y);
  89. if(!y) tr[u].cnt = 0;
  90. else tr[u].cnt = 1;
  91. return;
  92. }
  93. int mid = (tr[u].L + tr[u].R) >> 1;
  94. if(pos <= mid) Change(u << 1,pos,y);
  95. else Change(u << 1 | 1,pos,y);
  96. tr[u].P = max(tr[u << 1].P,tr[u << 1 | 1].P);
  97. tr[u].cnt = tr[u << 1].cnt + Calc(u << 1 | 1,tr[u << 1].P);
  98. }
  99. void Solve() {
  100. read(N);read(M);
  101. build(1,1,N);
  102. int x,y;
  103. for(int i = 1 ; i <= M ; ++i) {
  104. read(x);read(y);
  105. Change(1,x,y);
  106. out(tr[1].cnt);enter;
  107. }
  108. }
  109. int main() {
  110. #ifdef ivorysi
  111. freopen("f1.in","r",stdin);
  112. #endif
  113. Solve();
  114. }

【洛谷】P4198 楼房重建的更多相关文章

  1. 洛谷P4198 楼房重建 (分块)

    洛谷P4198 楼房重建 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题, ...

  2. 洛谷 P4198 楼房重建 题解

    题面 首先你要知道题问的是什么:使用一种数据结构,动态地维护以1为起点地最长上升子序列(把楼房的高度转化成斜率地序列)的长度: 怎么做?线段树! 我们在线段树上维护两个东西:1.这个区间内斜率的最大值 ...

  3. 洛谷P4198 楼房重建 单调栈+线段树

    正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...

  4. 洛谷P4198 楼房重建(线段树)

    题意 题目链接 Sol 别问我为什么发两遍 就是为了骗访问量 这个题的线段树做法,,妙的很 首先一个显然的结论:位置\(i\)能被看到当且仅当\(\frac{H_k}{k} < \frac{H_ ...

  5. 洛谷P4198 楼房重建

    题意:给定序列,每次修改一个值,求前缀最大值的个数. 解:线段树经典应用. 每个节点维护最大值和该区间前缀最大值个数. 发现我们不用下传标记,只需要合并区间. 需要实现一个函数int ask([l r ...

  6. 洛谷 P4198 楼房重建

    思路 此题可转化为以下模型 给定序列\(a[1...n]\),支持单点修改,每次求区间单调栈大小 \(n,Q\le 10^5\) 区间单调栈是什么呢?对于一个区间,建立一个栈,首先将第一个元素入栈,从 ...

  7. 洛谷 P4198 楼房重建 线段树维护单调栈

    P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...

  8. P4198 楼房重建

    P4198 楼房重建 集中写博客= = 首先把高度变成斜率 然后就比较玄学了,首先用线段树维护一个区间的斜率最大值,和只看这个区间时能看见的楼房个数ans 然后更新时先更新max,再处理神奇的ans ...

  9. 洛谷P1119-灾后重建-floyd算法

    洛谷P1119-灾后重建 题目描述 给出\(B\)地区的村庄数NN,村庄编号从\(0\)到\(N-1\),和所有\(M\)条公路的长度,公路是双向的. 给出第\(i\)个村庄重建完成的时间\(t_i\ ...

  10. 洛谷 P3905 道路重建

    题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...

随机推荐

  1. 字符编码问题mysql

    2019-02-27 07:32:17.108 ERROR 21745 --- [nio-8086-exec-2] c.h.h.rest.configurer.WebMvcConfigurer : 接 ...

  2. BZOJ 2125: 最短路

    2125: 最短路 Time Limit: 1 Sec  Memory Limit: 259 MBSubmit: 756  Solved: 331[Submit][Status][Discuss] D ...

  3. BZOJ 4764: 弹飞大爷

    4764: 弹飞大爷 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 4  Solved: 4[Submit][Status][Discuss] Des ...

  4. 解题:HAOI 2015 按位或

    题面 Min-Max容斥:对于集合S $min(S)=\sum_{s∈S}(-1)^{|s|+1}max(s)$ $max(S)=\sum_{s∈S}(-1)^{|s|+1}min(s)$ 那么这个题 ...

  5. POJ 3660 Cow Contest / HUST 1037 Cow Contest / HRBUST 1018 Cow Contest(图论,传递闭包)

    POJ 3660 Cow Contest / HUST 1037 Cow Contest / HRBUST 1018 Cow Contest(图论,传递闭包) Description N (1 ≤ N ...

  6. centos7下设置opencv环境变量

    最近要装YOLO,但是MAKE的时候总是找不到OPENCV的路径, 原因是:我以前卸载过一次OPENCV,然后自己重新安装了opencv2.4.10,  因为当时只在QT 中用,所以编译完也没有设置环 ...

  7. Nginx的基本配置案例

    Nginx的基本配置案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx配置虚拟主机   .操作系统环境 [root@yinzhengjie ~]# cat /etc ...

  8. python删除列表元素remove,pop,del

    python删除列表元素 觉得有用的话,欢迎一起讨论相互学习~Follow Me remove 删除单个元素,删除首个符合条件的元素,按值删除,返回值为空 List_remove = [1, 2, 2 ...

  9. 流媒体服务器之————EasyDarwin开源流媒体服务器:编译、配置、部署

    源码下载地址:https://github.com/EasyDarwin/EasyDarwin/archive/v7.0.5.zip 查看 Ubuntu 的版本号 sudo lsb_release - ...

  10. Python 入门基础10 --函数基础3 函数对象、名称空间、装饰器

    今日内容 1.函数对象 2.名称空间与作用域 3.函数的嵌套调用与闭包 4.装饰器 一.函数对象 1.1 定义 函数名存放的就是函数地址,所以函数名也就是对象,称之为函数对象 1.2 函数对象的应用 ...