当前位置: 首页 > news >正文

[bzoj2957]楼房重建

来自FallDream的博客,未经允许,请勿转载,谢谢。


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

n,m<=10^5

 

省队集训讲到了这东西是个经典模型 我听的一脸懵 赶紧补一发

简单点说就是要动态维护上升子序列长度

考虑线段树,每个线段记录只考虑这个区间的答案 顺便记下区间最大值 

考虑合并

如果右区间最大值小等于左区间,那么显然右区间不会贡献答案。

不然的话考虑右区间的两个子区间L,R在左区间的限制下能产生的贡献

如果右区间的左区间L的最大值也小等于左区间的最大值,那么直接递归区间R考虑即可。

不然的话,递归考虑区间L,这时候左区间相当于对区间R没有限制,所以这时候区间R贡献的答案是右区间的答案减去区间L的答案。

复杂度显然是nlog^2n的

#include<iostream>
#include<cstdio>
#define MN 100000
using namespace std;
inline int read()
{
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x;
}
struct{int l,r,ans;double mx;}T[MN*4+5];
int n,m;

int Calc(int x,double v)
{
    if(T[x].l==T[x].r) return T[x].mx>v;
    if(T[x<<1].mx>v) return Calc(x<<1,v)+T[x].ans-T[x<<1].ans;
    else return Calc(x<<1|1,v);
}

void update(int x)
{
    int l=x<<1,r=x<<1|1;
    T[x].ans=T[l].ans;
    T[x].mx=max(T[l].mx,T[r].mx);
    if(T[r].mx>T[l].mx) T[x].ans+=Calc(r,T[l].mx);
}

void Build(int x,int l,int r)
{
    T[x].mx=0;T[x].ans=1;
    if((T[x].l=l)==(T[x].r=r))return;
    int mid=l+r>>1;
    Build(x<<1,l,mid);
    Build(x<<1|1,mid+1,r);
}

void Modify(int x,int k,double v)
{
    if(T[x].l==T[x].r){T[x].mx=v;return;}
    int mid=T[x].l+T[x].r>>1;
    Modify(x<<1|(k>mid),k,v);
    update(x);
}

int main()
{
    n=read();m=read();
    Build(1,0,n);
    for(int i=1,j;i<=m;++i)
        j=read(),Modify(1,j,(double)read()/j),printf("%d\n",T[1].ans-1);
    return 0;
}

转载于:https://www.cnblogs.com/FallDream/p/bzoj2957.html

相关文章:

  • 杨辉三角的几种方法
  • 标题四
  • 3种上传图片并实现预览的方法
  • 暑假小集训
  • [无线路由] “免费”斐讯K2路由器刷OpenWRT(实战MWAN多宽带网速叠加)
  • 静态变量
  • Java字节数组和16进制字符串的互相转化
  • 多进程与多线程的区别
  • java线程详细介绍
  • let 和 const 命令
  • 简单的请求-处理-响应
  • oracle 在已有表新增列内批量加数据
  • 值得追随
  • 1、hive安装详细步骤
  • 学习中遇到的问题
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • .pyc 想到的一些问题
  • @jsonView过滤属性
  • 2017-08-04 前端日报
  • FineReport中如何实现自动滚屏效果
  • Java应用性能调优
  • laravel 用artisan创建自己的模板
  • Python_OOP
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 看域名解析域名安全对SEO的影响
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 前端学习笔记之观察者模式
  • 入门到放弃node系列之Hello Word篇
  • 算法之不定期更新(一)(2018-04-12)
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 问题之ssh中Host key verification failed的解决
  • 线性表及其算法(java实现)
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #1014 : Trie树
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #laravel 通过手动安装依赖PHPExcel#
  • (1) caustics\
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (poj1.3.2)1791(构造法模拟)
  • (Python第六天)文件处理
  • (二)JAVA使用POI操作excel
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (接口自动化)Python3操作MySQL数据库
  • (南京观海微电子)——COF介绍
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (区间dp) (经典例题) 石子合并
  • (十八)SpringBoot之发送QQ邮件
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (五)关系数据库标准语言SQL
  • (循环依赖问题)学习spring的第九天
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)使用VMware vSphere标准交换机设置网络连接
  • ***php进行支付宝开发中return_url和notify_url的区别分析