P4198 楼房重建

题目链接

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

题目描述

小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。

为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。

施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi(高度可以比原来大—修建,也可以比原来小—拆除,甚至可以保持不变—建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?

输入输出格式

输入格式:

第一行两个正整数N,M

接下来M行,每行两个正整数Xi,Yi

输出格式:

M行,第i行一个整数表示第i天过后小A能看到的楼房有多少栋

输入输出样例

输入样例#1:

3 4

2 4

3 6

1 1000000000

1 1

输出样例#1:

1

1

1

2

说明

对于所有的数据\(1<=Xi<=N,1<=Yi<=10^9\)

\(N,M<=100000\)

题解

线段树维护,记录一个max,sum即可,代码很短,但是有个点需要注意,我在代码相应位置标记了。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define N 100050
  5. int n,m;
  6. struct Tree{int l,r,sum; double max;}tr[N<<2];
  7. template<typename T>void read(T&x)
  8. {
  9. ll k=0; char c=getchar();
  10. x=0;
  11. while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
  12. if (c==EOF)exit(0);
  13. while(isdigit(c))x=x*10+c-'0',c=getchar();
  14. x=k?-x:x;
  15. }
  16. void read_char(char &c)
  17. {while(!isalpha(c=getchar())&&c!=EOF);}
  18. int get_sum(int x,double tt)
  19. {
  20. if (tr[x].max<=tt)return 0;
  21. if (tr[x].l==tr[x].r)return tr[x].sum;
  22. Tree &a=tr[x<<1],&b=tr[x<<1|1];
  23. if (tt>=a.max)return get_sum(x<<1|1,tt);
  24. else return get_sum(x<<1,tt)+tr[x].sum-a.sum;//这里不能写成 get_sum(x<<1,tt)+b.sum;
  25. }
  26. void push_up(int x)
  27. {
  28. Tree &a=tr[x<<1],&b=tr[x<<1|1];
  29. tr[x].max=max(a.max,b.max);
  30. tr[x].sum=a.sum+get_sum(x<<1|1,a.max);
  31. }
  32. void bt(int x,int l,int r)
  33. {
  34. tr[x].l=l; tr[x].r=r;
  35. if (l==r)return;
  36. int mid=(l+r)>>1;
  37. bt(x<<1,l,mid);
  38. bt(x<<1|1,mid+1,r);
  39. }
  40. void update(int x,int p,double tt)
  41. {
  42. if (tr[x].l==tr[x].r)
  43. {
  44. tr[x].max=tt;
  45. tr[x].sum=1;
  46. return;
  47. }
  48. int mid=(tr[x].l+tr[x].r)>>1;
  49. if (p<=mid)update(x<<1,p,tt);
  50. else update(x<<1|1,p,tt);
  51. push_up(x);
  52. }
  53. int main()
  54. {
  55. #ifndef ONLINE_JUDGE
  56. freopen("aa.in","r",stdin);
  57. #endif
  58. read(n); read(m);
  59. bt(1,1,n);
  60. for(int i=1;i<=m;i++)
  61. {
  62. int x;double tt;
  63. read(x); read(tt);tt=tt/x;
  64. update(1,x,tt);
  65. printf("%d\n",tr[1].sum);
  66. }
  67. }
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define N 100050
  5. int n,m;
  6. struct Tree{int l,r,sum; double max;}tr[N<<2];
  7. template<typename T>void read(T&x)
  8. {
  9. ll k=0; char c=getchar();
  10. x=0;
  11. while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
  12. if (c==EOF)exit(0);
  13. while(isdigit(c))x=x*10+c-'0',c=getchar();
  14. x=k?-x:x;
  15. }
  16. void read_char(char &c)
  17. {while(!isalpha(c=getchar())&&c!=EOF);}
  18. int get_sum(int x,double tt)
  19. {
  20. if (tr[x].max<=tt)return 0;
  21. if (tr[x].l==tr[x].r)return tr[x].sum;
  22. Tree &a=tr[x<<1],&b=tr[x<<1|1];
  23. if (tt>=a.max)return get_sum(x<<1|1,tt);
  24. else return get_sum(x<<1,tt)+tr[x].sum-a.sum;//这里不能写成 get_sum(x<<1,tt)+b.sum;
  25. }
  26. void push_up(int x)
  27. {
  28. Tree &a=tr[x<<1],&b=tr[x<<1|1];
  29. tr[x].max=max(a.max,b.max);
  30. tr[x].sum=a.sum+get_sum(x<<1|1,a.max);
  31. }
  32. void bt(int x,int l,int r)
  33. {
  34. tr[x].l=l; tr[x].r=r;
  35. if (l==r)return;
  36. int mid=(l+r)>>1;
  37. bt(x<<1,l,mid);
  38. bt(x<<1|1,mid+1,r);
  39. }
  40. void update(int x,int p,double tt)
  41. {
  42. if (tr[x].l==tr[x].r)
  43. {
  44. tr[x].max=tt;
  45. tr[x].sum=1;
  46. return;
  47. }
  48. int mid=(tr[x].l+tr[x].r)>>1;
  49. if (p<=mid)update(x<<1,p,tt);
  50. else update(x<<1|1,p,tt);
  51. push_up(x);
  52. }
  53. int main()
  54. {
  55. #ifndef ONLINE_JUDGE
  56. freopen("aa.in","r",stdin);
  57. #endif
  58. read(n); read(m);
  59. bt(1,1,n);
  60. for(int i=1;i<=m;i++)
  61. {
  62. int x;double tt;
  63. read(x); read(tt);tt=tt/x;
  64. update(1,x,tt);
  65. printf("%d\n",tr[1].sum);
  66. }
  67. }

洛谷 P4198 楼房重建 线段树维护单调栈的更多相关文章

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

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

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

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

  3. [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)

    题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...

  4. [Luogu P4198]楼房重建(线段树)

    题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...

  5. 洛谷 P4198 楼房重建

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

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

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

  7. luogu P4198 楼房重建——线段树

    题目大意: 小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线 ...

  8. [BZOJ 2957]楼房重建(THU2013集训)(线段树维护单调栈)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2957 分析: 根据题意,就是比较斜率大小 只看一段区间的话,那么这段区间能看见的楼房数量就是这 ...

  9. 洛谷 P4198 楼房重建 题解

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

随机推荐

  1. Magic Points ZOJ - 4032

    The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple Magic Points ZOJ - ...

  2. web软件测试基础系统测试简化理论

    系统测试点主要如下 1.系统测试基础-2.测试对象与测试级别-3.系统测试类型-4.系统测试方法-5.系统测试之软件测试质量. 1.系统测试:是尽可能彻底地检查出程序中的错误,提高软件系统的可靠性. ...

  3. Qt内的各种路径(让人迷惑)

    Qt里面各种获取程序路径或者当前路径的写法,在此梳理一下,以防今后开发的程序中路径不统一 1.利用QDir获取路径 QDir::currentPath() 此路径是项目编译生成的路径即可执行文件所在目 ...

  4. Cesium中级教程6 - 3D Models 三维模型

    3D Models 三维模型 本教程将教您如何通过Primitive API转换.加载和使用Cesium中的三维模型.如果你是Cesium的新用户,可能需要阅读三维模型部分的(空间数据可视化教程)[h ...

  5. Objective-C如何自己实现一个for-each语法形式

    我们在用Objective-C编写程序时,很多时候会用到NSArray来作为线性列表来使用.我们在枚举这个数组所有元素的使用可以通过下列方法进行: for(id obj in anArray) { } ...

  6. c++ 容器中元素计数

    #include <iostream>#include <algorithm>#include <vector>#include <functional> ...

  7. OpenStack v.s. Kubernetes

    目录 文章目录 目录 What are the differences with OpenStack and Kubernetes? Why OpenStack & Kubernetes? W ...

  8. 目标检测 - TridentNet

    转载: https://zhuanlan.zhihu.com/p/54334986 http://haha-strong.com/2019/07/25/20190725-TridentNet/ 开源代 ...

  9. uni-app 使用Vuex+ (强制)登录

    一.在项目的根目录下新建一个store文件夹,然后在文件夹下新建一个index.js文件 二.在新建的index.js下引入vue和vuex,具体如下: //引入vue和vuex import Vue ...

  10. Sprint Retrospective - 回顾的重要性

    在Scrum中,每个Sprint结束的时候会有两个会议(Sprint Review/Demo和Sprint Retrospective回顾).这两个会议是对过去的一个Sprint的一个总结,其中Rev ...