题目描述

小 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 能看到的楼房有多少栋。

输入输出

输入
3 4
2 4
3 6
1 1000000000
1 1
输出
1
1
1
2

说明/提示

对于100%的数据,1≤Xi≤N,1≤Yi≤10^9, 1≤N,M≤10^5。

题目分析

高的楼房会挡住后面低的楼房。但遮挡并不仅仅是简单的大于后面的就会遮挡,比如:2位置上高度为4的楼房可以挡住4位置上高度为8的楼房。仔细思考不难发现:遮挡是基于斜率的,即:后面的楼房如果不会被前面的楼房遮挡,那么后面这栋楼房的斜率一定大于前面所有楼房斜率

要想快速的维护最大值,可以用线段树来维护。线段树中维护两个信息:每段的斜率最大值slo和从当前端的左边向右看能看到多少栋楼楼len

最大值slo比较的好维护,每段只需要取左右子段的最大值即可。
我们主要来看一下len如何来维护:
首先我们需要一个函数getLen()来求出在前面有一个斜率为 l m lm lm的遮挡物下,这一段能够露出多少栋楼来(这个函数的写法具体可以看代码)。
有了这个函数后,就可以维护len了,本段的len=左子段的len+getLen(右子段 , 左子段的最大斜率)。

代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#define LL long long
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N=1e5+5,INF=0x3f3f3f3f;
struct Node{int l,r;double slo;int len;
}tr[N*4];
double a[N];            //存某个位置楼房的斜率
int getLen(int u,double lm)     //在前面有一个斜率为lm的遮挡下,u段能够露出多少栋楼
{if(lm>=tr[u].slo) return 0;                //如果lm大于等于u段的斜率最大值,答案为0if(a[tr[u].l]>lm) return tr[u].len;        //如果u段左端点的斜率大于lm,那么答案就是u段的lenif(tr[u].l==tr[u].r) return 0;            //如果此段只有一个数,这个数还小于lm,答案是0int mid=tr[u].l+tr[u].r>>1;//如果lm大于等于左子段的slo,那么只需要递归求出右子段的答案即可(左子段答案为0)if(lm>=tr[u<<1].slo) return getLen(u<<1|1,lm);return getLen(u<<1,lm)+tr[u].len-tr[u<<1].len;//如果lm小于左子段的最大值,那么递归求出左子段的答案,因为左子段的slo大,因此右子段的答案不受影响
}
void pushup(int u)
{tr[u].slo=max(tr[u<<1].slo,tr[u<<1|1].slo);tr[u].len=tr[u<<1].len+getLen(u<<1|1,tr[u<<1].slo);
}
void build(int u,int l,int r)           //建树
{tr[u]={l,r};if(l==r) return;int mid=l+r>>1;build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
void modify(int u,int x,int c)          //单点修改,将x位置的高度改为c
{if(tr[u].l==tr[u].r){tr[u].slo=(double)c/x;         //斜率为c/xtr[u].len=1;}else {int mid=tr[u].l+tr[u].r>>1;if(mid>=x) modify(u<<1,x,c);else modify(u<<1|1,x,c);pushup(u); }
}
int main()
{int n,m;scanf("%d%d",&n,&m);build(1,1,n);while(m--){int x,y;scanf("%d%d",&x,&y);a[x]=(double)y/x;modify(1,x,y);printf("%d\n",tr[1].len);        //每次修改后的答案即为tr[1].len}return 0;
}

P4198 楼房重建(思维)相关推荐

  1. P4198 楼房重建 线段树 + 区间合并

    传送门 文章目录 题意: 思路: 题意: 题面有点问题,按照人类正常的理解来就好啦. 思路: 可以想到维护每个位置的一个斜率,模拟的话就是从第一个位置开始向后选,当某个位置斜率大于当前位置的时候,答案 ...

  2. LG P4198 楼房重建(线段树)

    LG P4198 楼房重建 Solution 基础的线段树题,虽然我还不熟练就是了. 大概就是单点修改,求全局的极大子序列. 我们需要维护一个区间最大值aaa和极大子序列长度sss. 合并xxx的左右 ...

  3. [luogu P4198] 楼房重建(线段树 + 思维)

    luogu 楼房重建 problem solution code problem 洛谷链接 solution 非常巧妙的一道题,对线段树的运用很灵活. 显然这个与原点的连线可以想到将每个点转化为与原点 ...

  4. [Luogu] P4198 楼房重建

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

  5. P4198 楼房重建

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

  6. 线段树-楼房重建-洛谷-P4198

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

  7. BZOJ 2957楼房重建

    传送门 线段树 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include< ...

  8. 2957: 楼房重建

    2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 1579  Solved: 754 [Submit][Status][Discu ...

  9. bzoj 2957: 楼房重建(线段树+递归)

    2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2778  Solved: 1314 [Submit][Status][Disc ...

最新文章

  1. \r与\n有何差别,编码的时候应该怎样使用
  2. 技术图文:双指针在链表问题中的应用
  3. 「Excel技巧」Excel技巧之如何看文件里的宏?
  4. 【Python爬虫学习笔记4】结合Xpath与lxml库解析数据
  5. 山西上党残疾男子“只”手脱贫 带领村民增收
  6. leetcood学习笔记-226- 翻转二叉树
  7. 高达100亿美元!美国国防部将IBM和甲骨文双双踢出了云计算合同;华为任正非说了,华为对向苹果等对手出售5G芯片保持开放的态度...
  8. 关于spring注入
  9. 【百度贾磊】汉语语音识别技术重大突破:LSTM+CTC详解(22PPT)
  10. 联想r720自带杜比驱动下载_给心爱的本本装上杜比音效
  11. (Inside Out)Web地图坐标系——谷歌的无奈
  12. Git正解 脱水版 【9. 其他VCS系统】
  13. Microsoft Visual SourceSafe 使用说明详解
  14. (16)万能查询还是万恶查询?
  15. 2021年安全生产模拟考试(建筑起重机司机-物料提升机模拟考试题库)安考星
  16. 黄金期货单位(黄金期货单位有哪些)
  17. nRF52832 — 提高蓝牙BLE的数据传输速率
  18. 逆变器运用到的c语言算法,总结逆变电源常用到的六种控制算法
  19. 极光开发者周刊【No.0423】
  20. swiper入门小练习-移动端实现上下滑动翻整个页面(一)

热门文章

  1. github使用 9个步骤
  2. 服务器ftp连接成功不显示文件,ftp服务器不显示文件
  3. SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
  4. mysql any、some和all的用法
  5. 计算机显示未在机构中注册,[.Net]明明白白的解决'未在本地计算机上注册Microsoft.ACE.OLEDB.12.0'问题...
  6. Java开发相关官方存档下载地址
  7. 强制性认证覆盖百余种工业产品
  8. 想算法无头绪,咋办?
  9. BCompare报应用程序发生错误
  10. excel批处理:如何按给定目录批量创建系列文件夹