Description

  小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。
  为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。
  施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi(高度可以比原来大---修建,也可以比原来小---拆除,甚至可以保持不变---建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?

Input

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

Output

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

Sample Input

3 4
2 4
3 6
1 1000000000
1 1

Sample Output

1
1
1
2
数据约定
  对于所有的数据1<=Xi<=N,1<=Yi<=10^9,N,M<=100000
 
 
 
=========华丽丽的分割线============
虽然是一个清华集训的题目,不过还是可做的嘛。。。
一开始的时候自己写了一个程序,然后怎么都没有调出来。
考虑本题,给出一个数列,然后要求支持单点修改以及询问比自己左边所有数都大的数就几个。
考虑线段树,维护出一段中的高度最大值以及别的数都不考虑的情况下(这个一定不能漏)比这样的数有几个。
考虑合并两个线段,高度的最大值是很容易合并的,直接取一个max就可以了。
对于贡献度,我们发现一个线段的左半部分所有满足的数在原来的线段中一定满足,于是我们只需要考虑右半部分。
我们写一个函数calc(node,k)表示node这个线段在左侧有一个大小为k的数的时候内部满足条件的数的个数。
于是发现如果这个线段的左半部分的最大值小于等于k,那么左半部分贡献就是0,直接返回calc(node*2+1,k),
如果左半部分最大值大于k,那么右半部分原本的个数是不会变的,然后再加上calc(node*2,k)就可以了,
时间复杂度O(nlog^2n),
听说这题卡精度,在吕爷爷的帮助下我学会了fraction,代码如下:

 #include <bits/stdc++.h>
#define Maxn 100007
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct fraction
{
int dx,dy;
};
bool operator >(fraction a, fraction b)
{
return (1LL*a.dx*b.dy>1LL*a.dy*b.dx);
}
bool operator >=(fraction a, fraction b)
{
return (1LL*a.dx*b.dy>=1LL*a.dy*b.dx);
}
bool operator <(fraction a, fraction b)
{
return (1LL*a.dx*b.dy<1LL*a.dy*b.dx);
}
bool operator <=(fraction a, fraction b)
{
return (1LL*a.dx*b.dy<=1LL*a.dy*b.dx);
}
int n,m;
struct seg
{
int lx,rx,cnt;
fraction hmax;
};
seg tree[Maxn*];
void build(int node, int l, int r)
{
tree[node].lx=l,tree[node].rx=r,tree[node].cnt=;
tree[node].hmax=(fraction){,};
if (tree[node].lx==tree[node].rx) return;
int mid=(l+r)/;
build(node*,l,mid),build(node*+,mid+,r);
}
int calc(int node, fraction h)
{
if (tree[node].hmax<=h) return ;
if (tree[node].lx==tree[node].rx) return ;
if (tree[node*].hmax<=h) return calc(node*+,h);
else return tree[node].cnt-tree[node*].cnt+calc(node*,h);
}
void update(int node, int pos, fraction h)
{
if (tree[node].rx<pos) return;
if (tree[node].lx>pos) return;
if (tree[node].lx==tree[node].rx)
{
tree[node].hmax=h;
tree[node].cnt=;
return;
}
update(node*,pos,h),update(node*+,pos,h);
tree[node].hmax=max(tree[node*].hmax,tree[node*+].hmax);
tree[node].cnt=tree[node*].cnt+calc(node*+,tree[node*].hmax);
}
int main()
{
n=read(),m=read();
build(,,n);
while (m--)
{
int x=read(),y=read();
update(,x,(fraction){y,x});
printf("%d\n",tree[].cnt);
}
return ;
}
 

【数据结构】bzoj2957楼房重建的更多相关文章

  1. BZOJ2957: 楼房重建(线段树&LIS)

    2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3727  Solved: 1793[Submit][Status][Discus ...

  2. Bzoj2957 楼房重建

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1516  Solved: 723[Submit][Status][Discuss] Descripti ...

  3. [bzoj2957][楼房重建] (线段树)

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

  4. 【分块】bzoj2957 楼房重建

    http://www.cnblogs.com/wmrv587/p/3843681.html ORZ 分块大爷.思路很神奇也很清晰. 把 块内最值 和 块内有序 两种良好的性质结合起来,非常棒地解决了这 ...

  5. 【经典问题】bzoj2957: 楼房重建

    经典问题:动态维护上升子序列长度 进阶问题:[经典问题]#176. 栈 Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无 ...

  6. BZOJ2957 楼房重建 【线段树】

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

  7. bzoj2957 楼房重建——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2957 线段树维护两个值:cnt 能看到的最多楼房数: mx 最大斜率数: 对于一段区间,从左 ...

  8. BZOJ2957: 楼房重建(分块)

    题意 题目链接 Sol 自己YY出了一个\(n \sqrt{n} \log n\)的辣鸡做法没想到还能过.. 可以直接对序列分块,我们记第\(i\)个位置的值为\(a[i] = \frac{H_i}{ ...

  9. bzoj2957楼房重建

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2957 线段树.每个点记录斜率,要一个单增的序列长度(从1开始). 线段树每个点记录自己区间的 ...

随机推荐

  1. C# Winform 实现屏蔽键盘的win和alt+F4的实现代码

    最近在做一个恶搞程序,就是打开后,程序获得桌面的截图然后,然后全屏显示在屏幕上,用户此时则不能进行任何操作. 此时希望用户不能通过键盘alt+F4来结束程序及通过Win的组合键对窗口进行操作.我在网上 ...

  2. Hibernate-ORM:13.Hibernate中的连接查询

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客将会解释Hibernate中的连接查询(各种join) 一,目录 1.内链接 1.1显式内连接(inn ...

  3. spring、spring-data-redis整合使用

    一.Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 从2010年3月15日起,Redis的开发工作由VMwa ...

  4. Django admin操作

      无名小妖     昵称:无名小妖园龄:1年6个月粉丝:22关注:1 +加关注 搜索     常用链接 我的随笔 我的评论 我的参与 最新评论 我的标签 我的标签 Python(1) python3 ...

  5. 获取.jar文件运行时所处的路径

    在Windows控制台中运行.jar文件时的两种环境: (1)控制台当前所在目录是.jar文件所在的目录 (2)控制台当前所在目录不是.jar文件所在的目录 我的期望: 我希望在上述两种环境下均可以得 ...

  6. CSP201409-1:相邻数对

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  7. 常见 SQL语句使用 增删改查

    一.常见的增删改查(一).查:1.SELECT 列名称 FROM 表名称,其中列名可以是多个,中间用豆号分开,如SELECT LastName,FirstName FROM Persons: 2.SE ...

  8. [leetcode-652-Find Duplicate Subtrees]

    Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...

  9. 我和C语言程序

    姓名:江超鸿 学号:160809129 爱好:打台球.听音乐 博客地址:https://www.cnblogs.com/jiangchaohong/ C语言:对于c语言程序来说,我是第一次接触,对它的 ...

  10. 【Linux】——搭建redis

    1.准备安装文件 redis-3.0.5.tar.gz redis-desktop-manager(可视化管理工具) 2.解压.编译 软件存放目录:/usr/local/software 解压存放路径 ...