每个楼房,还有修改操作。简单的想到用线段树来维护信息。

显然线段树只需要维护y/x即可,对于每一个楼房,能看见的条件就是前面楼房的y/x的严格小于当前楼房的y/x。

线段树的区间修改不再赘述。

那么怎么维护可以看到的楼房数呢?

考虑在线段树的每一个节点上用一个变量sum来表示从这个节点的左端点向右端点看时能看到多少楼房。

假设现在有一区间:1,5,8,0,7,9。维护这个区间信息的节点编号为x

x<<1维护的区间是1,5,8,从18看可以看到三个楼房,故x<<1的sum的值为3

x<<1|1维护的区间是0,7,9,从09看也可以看到三个楼房,故x<<1|1的sum的值也为3

难道x的sum值也为3+3=6?错!

这显然是不能加在一起的,x的sum的值为4。

为什么会错呢?应为右儿子x<<1|1的观察视角不是从1开始的,是从0开始的。

显然0被挡住了。

显然,为什么这道题是紫题,主要难在的怎么上传信息。(不然就是黄牌了)

首先考虑每个线段树节点在维护一个mxmx代表这个节点所代表的区间中所有的楼房中最高的高度。

上传时,由于两个儿子的sum值是已经处理好的,而左儿子的视角是跟x的视角一样的(对于上面的例子来说都是1),可以直接上传,即sum(x)+=sum(x<<1)

对于右儿子,考虑递归处理右儿子的区间,递归时带一个Mx变量表示x的左儿子的最高的楼房(右儿子再左儿子后面,原因下面解释),递归的返回值是当前处理区间可以被看到的楼房数(从x的视角看)

对于现在处理的每一个区间:

  • 如果这个区间的最高的楼房的高度都<=Mx(全部被挡住了),立即return 0
  • 如果这个区间最左边的楼房高度>Mx(可以看到),那么return 当前区间维护的sum值。
  • 如果这个区间只代表一个楼房,直接判断其能否被看到即可。
  • 对于剩下的情况,递归儿子,分两种情况讨论:

    • 如果左儿子的最高的楼房小于Mx(不能对答案有任何贡献),直接递归右儿子。
    • 否则,递归左儿子,右儿子能看到的楼房个数为当前区间sum-左儿子sum即可,(应为下面已经更新好了,只需要直接调用就好了。)

Code(文中的sum用l代替):

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int N=1e5+2;
struct Node {
double mx;
int l;
#define m(x) tree[x].mx
#define l(x) tree[x].l
} tree[N<<2];
int n,m;
double val[N];
inline void pushup_max(int x) {
m(x)=max(m(x<<1),m(x<<1|1));
}
inline int pushup_sum(double Mx,int x,int l,int r) {
if(m(x)<Mx)return 0;
if(val[l]>Mx)return l(x);
if(l==r)return val[l]>Mx;
int mid=(l+r)>>1;
if(m(lson)<=Mx)return pushup_sum(Mx,rson,mid+1,r);
else return pushup_sum(Mx,lson,l,mid)+l(x)-l(lson);
}
inline void change(int x,int l,int r,int pos,int value) {
if(l==r&&l==pos) {
m(x)=(double)value/pos;
l(x)=1;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)change(lson,l,mid,pos,value);
else if(pos>mid)change(rson,mid+1,r,pos,value);
pushup_max(x);
l(x)=l(lson)+pushup_sum(m(lson),rson,mid+1,r);
}
int main() {
scanf("%d%d",&n,&m);
for(register int x,y,i=1; i<=m; ++i) {
scanf("%d%d",&x,&y);
val[x]=(double)y/x;
change(1,1,n,x,y);
printf("%d\n",l(1));
}
return 0;
}

最新文章

  1. JQ下的常见插件
  2. LoadRunner常用函数列表
  3. 不可不知的C#基础 4. 延迟加载 -- 提高性能
  4. 更改Magento的base url
  5. 一目了然c++虚基类!
  6. 如何打开mo文件并修改 PoEdit
  7. css伪类伪元素
  8. FineUIMvc随笔(6)对比WebForms和MVC中表格的数据库分页
  9. Bootstrap 常用组件汇总
  10. 31. leetcode 122. Best Time to Buy and Sell Stock II
  11. jQuery 插件格式 规范
  12. Paho -物联网 MQTT C Cient的实现和详解
  13. jmeter beanshell 中使用map
  14. codevs3044
  15. H5新特性之geolocation
  16. JAVA实现微信支付V3
  17. 关于Unity中Shader的使用
  18. CSRmesh Application
  19. VMware workstation 设定开机引导等待时间
  20. CF451E Devu and Flowers(组合数)

热门文章

  1. bzoj4276
  2. C++实现二叉树(建树,前序,中序,后序)递归和非递归实现
  3. Mysql数据库基础操作
  4. arcgis for silverlight 鼠标点击地图获取当前经纬度
  5. jQuery入坑指南
  6. 压力测试之jmeter使用
  7. Unix\Linux | 总结笔记 | 用户管理
  8. 《windows核心编程系列》二十二谈谈修改导入段拦截API。
  9. head first python /chapter7 web(python 3 转 python 2.7)
  10. docker学习教程