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即可,代码很短,但是有个点需要注意,我在代码相应位置标记了。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
int n,m;
struct Tree{int l,r,sum; double max;}tr[N<<2];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
int get_sum(int x,double tt)
{
if (tr[x].max<=tt)return 0;
if (tr[x].l==tr[x].r)return tr[x].sum;
Tree &a=tr[x<<1],&b=tr[x<<1|1];
if (tt>=a.max)return get_sum(x<<1|1,tt);
else return get_sum(x<<1,tt)+tr[x].sum-a.sum;//这里不能写成 get_sum(x<<1,tt)+b.sum;
}
void push_up(int x)
{
Tree &a=tr[x<<1],&b=tr[x<<1|1];
tr[x].max=max(a.max,b.max);
tr[x].sum=a.sum+get_sum(x<<1|1,a.max);
}
void bt(int x,int l,int r)
{
tr[x].l=l; tr[x].r=r;
if (l==r)return;
int mid=(l+r)>>1;
bt(x<<1,l,mid);
bt(x<<1|1,mid+1,r);
}
void update(int x,int p,double tt)
{
if (tr[x].l==tr[x].r)
{
tr[x].max=tt;
tr[x].sum=1;
return;
}
int mid=(tr[x].l+tr[x].r)>>1;
if (p<=mid)update(x<<1,p,tt);
else update(x<<1|1,p,tt);
push_up(x);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
read(n); read(m);
bt(1,1,n);
for(int i=1;i<=m;i++)
{
int x;double tt;
read(x); read(tt);tt=tt/x;
update(1,x,tt);
printf("%d\n",tr[1].sum);
}
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
int n,m;
struct Tree{int l,r,sum; double max;}tr[N<<2];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
int get_sum(int x,double tt)
{
if (tr[x].max<=tt)return 0;
if (tr[x].l==tr[x].r)return tr[x].sum;
Tree &a=tr[x<<1],&b=tr[x<<1|1];
if (tt>=a.max)return get_sum(x<<1|1,tt);
else return get_sum(x<<1,tt)+tr[x].sum-a.sum;//这里不能写成 get_sum(x<<1,tt)+b.sum;
}
void push_up(int x)
{
Tree &a=tr[x<<1],&b=tr[x<<1|1];
tr[x].max=max(a.max,b.max);
tr[x].sum=a.sum+get_sum(x<<1|1,a.max);
}
void bt(int x,int l,int r)
{
tr[x].l=l; tr[x].r=r;
if (l==r)return;
int mid=(l+r)>>1;
bt(x<<1,l,mid);
bt(x<<1|1,mid+1,r);
}
void update(int x,int p,double tt)
{
if (tr[x].l==tr[x].r)
{
tr[x].max=tt;
tr[x].sum=1;
return;
}
int mid=(tr[x].l+tr[x].r)>>1;
if (p<=mid)update(x<<1,p,tt);
else update(x<<1|1,p,tt);
push_up(x);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
read(n); read(m);
bt(1,1,n);
for(int i=1;i<=m;i++)
{
int x;double tt;
read(x); read(tt);tt=tt/x;
update(1,x,tt);
printf("%d\n",tr[1].sum);
}
}

洛谷 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. Java实例化对象过程中的内存分配

    Java实例化对象过程中的内存分配: https://blog.csdn.net/qq_36934826/article/details/82685791 问题引入这里先定义一个很不标准的“书”类,这 ...

  2. elasticsearch shield(5.0以下版本 权限认证)

    elasticsearch 5.0以下的版本要用到权限控制的话需要使用shield.下载地址: https://www.elastic.co/downloads/shield5.0以上的版本则可以使用 ...

  3. certbot 配置https屏蔽询问选项

    平常直接在终端,刷https时,要sudo certbot --nginx这样执行,但是中间会出现选项,让选择. 写程序用脚本操作时,希望跳过这些选项,就用--agree-tos 参数,一步到位. s ...

  4. win10设置开机开启数字锁定

    windows10开机小键盘默认关闭,网上查询修改InitialKeyboardIndicators键值为2,或者80000002,经过实际测试,均无效,键值8000000002有效,是中间8个0,开 ...

  5. LINUX 上 实现SNTP (时间同步)

    Network Time Protocol (NTP) 也是RHCE新增的考试要求. 学习的时候也顺便复习了一下如何设置Linux的时间,现在拿出来和大家分享 设置NTP服务器不难但是NTP本身是一个 ...

  6. 配置nginx支持path_info

    默认情况下,nginx是不支持path_info的,我们需要做些配置让它支持. location ~ \.php(.*)$ { root /var/www/nginx/html; fastcgi_pa ...

  7. linux rtc中废弃的接口和新的接口

    1. 废弃的接口 rtc_tm_to_time 2. 替换废弃接口的新接口 rtc_tm_sub

  8. 一百三十七:CMS系统之发布帖子前台布局

    把前面配置好的ueditor的文件复制到static下 把ueditor蓝图导入,注册 初始化ueditor //初始化ueditor$(function () { var ue = UE.getEd ...

  9. sersync+rsync做实时同步

    (1).实验环境 源主机:youxi1 192.168.5.101 目的主机:youxi2 192.168.5.102 目的:实时同步数据 sersync默认端口874,rsync默认端口873 (2 ...

  10. git_push报错

    转自 https://blog.csdn.net/u010042585/article/details/79378726 将本地项目push到GitHub时遇到的问题 .$ git remote ad ...