题目描述

小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


题解

线段树 分块+二分查找

题目大意说白了就是给定n个斜率,求这些斜率的连续递增数列(从1开始,每有一个比前一个大的就选定)的长度,多次修改。

看了下数据范围可以分块求。

先暴力搞定每个块的递增数列,把这些斜率从小到大塞到一个栈里边(时间复杂度O(n/b),b为块的大小)。

然后查找时从头开始,在每个块对应的栈中二分查找第一个斜率比前一个大的位置,这个位置和栈里面后边的位置都能被看到(时间复杂度O(blog(n/b)))。

总时间复杂度为O(n*(n/b + blog(n/b)))≈O(n*(n/b + blogn))。

这样一来b=√(n/logn)比较合算,但其实也没什么卵用,直接√n一块就行。

#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 100010
using namespace std;
int n , si , h[N];
struct data
{
int top , sta[400];
}a[400];
bool cmp(int a , int b)
{
if(!b) return h[a] > 0;
return (long long)h[a] * b > (long long)h[b] * a;
}
int main()
{
int m , i , si , p , l , r , mid , ans , tmp , last;
scanf("%d%d" , &n , &m) , n ++ ;
si = (int)sqrt(n);
while(m -- )
{
scanf("%d" , &p);
scanf("%d" , &h[p]);
l = p / si * si , r = min(n , (p / si + 1) * si);
a[p / si].top = 0;
for(i = l ; i < r ; i ++ )
if(cmp(i , a[p / si].sta[a[p / si].top]))
a[p / si].sta[++a[p / si].top] = i;
ans = 0 , last = 0;
for(i = 0 ; i <= (n - 1) / si ; i ++ )
{
l = 1 , r = a[i].top , tmp = 0;
while(l <= r)
{
mid = (l + r) >> 1;
if(cmp(a[i].sta[mid] , last)) tmp = mid , r = mid - 1;
else l = mid + 1;
}
if(tmp) last = a[i].sta[a[i].top] , ans += a[i].top - tmp + 1;
}
printf("%d\n" , ans);
}
return 0;
}

【bzoj2957】楼房重建 分块+二分查找的更多相关文章

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

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

  2. BZOJ_3343_教主的魔法_分块+二分查找

    BZOJ_3343_教主的魔法_分块+二分查找 题意:教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列被编号为 ...

  3. BZOJ 3343: 教主的魔法(分块+二分查找)

    BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved:  ...

  4. 【BZOJ2957】楼房重建 分块

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

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

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

  6. bzoj 2957 楼房重建 分块

    楼房重建 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=29 ...

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

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

  8. 【分块】bzoj2957 楼房重建

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

  9. 【tyvj1463】智商问题 [分块][二分查找]

    Background 各种数据结构帝~各种小姊妹帝~各种一遍AC帝~ 来吧! Description 某个同学又有很多小姊妹了他喜欢聪明的小姊妹 所以经常用神奇的函数来估算小姊妹的智商他得出了自己所有 ...

随机推荐

  1. Eclipse工具查看依赖的JDK、Maven源码方法

    一.Eclipse软件里查看JDK依赖源码 1.Window->Preferences->Java->Installed JREs 2.如图: 二.Eclipse软件里查看Maven ...

  2. Python3 operator模块关联代替Python2 cmp() 函数

    Python2 cmp() 函数 描述 cmp(x,y) 函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1. Python ...

  3. while,格式化输出

    1. while循环: while 条件: 代码块(循环体) num=1 while num<=5: print(num) num+=1 break:结束循环;停止当前本层循环 continue ...

  4. Leecode刷题之旅-C语言/python-67二进制求和

    /* * @lc app=leetcode.cn id=67 lang=c * * [67] 二进制求和 * * https://leetcode-cn.com/problems/add-binary ...

  5. vue---day01

    1.let和const var 全局作用域和函数作用域 存在变量提升 其实是个bug 可以重复声明 let 块级作用域 不存在变量提升 不能重复声明 const 常量 和let一样还有另外两个 定义的 ...

  6. CSS3复选框动画

    本示例实现了两种单选按钮动画效果,一种是移动,一种是滑块,以下是html布局以及css样式 html:这里使用了label标签的for属性,以此来绑定radio <div class=" ...

  7. 类的__new__方法使用

    class Person(object): def __init__(self): self.name ="aaa" def defineName(self): self.name ...

  8. linux里面的fork函数创建一个新进程

    由fork创建的新进程成为子进程,fork函数被调用一次,但是返回两次,

  9. c#一些常用的方法集合

    是从一个asp.net mvc的项目里看到的.挺实用的. 通过身份证号码获取出生日期和性别 通过身份证号码获取出生日期和性别 #region 由身份证获得出生日期 public static stri ...

  10. Android Studio引入AAR文件

    一.编译生成AAR文件 二.把AAR文件复制到项目的libs目录下 三.在项目的配置文件中加入如下代码: android { //other code repositories{ flatDir{ d ...