Luogu 4198 楼房重建
BZOJ 2957
挺妙的题。
先把题目中的要求转化为斜率,一个点$(x, y)$可以看成$\frac{y}{x}$,这样子我们要求的就变成了一个区间内一定包含第一个值的最长上升序列。
然后把这个序列开成线段树,维护一下区间内的答案$res$和最大值$mx$,显然对于叶子结点有$mx = a_l$,$res = 1$。
$mx$的更新非常简单直接取个最大值就好了,但是$res$的更新有一些复杂,对于一个区间$[l, r]$,左儿子$[l, mid]$的值可以直接加过来,因为左儿子一定会被选到,但是右儿子的值并不那么容易计算,我们用$solve(l, r, v)$表示区间$[l, r]$内第一个值超过$v$的元素必选的最长上升序列的大小,当$l == r$的时候,只要观察$mx$是否大于$v$就可以得到答案,而$solve$函数的合并则与左儿子区间的最大值有关,具体来说:当$mx_{lc} > v$的时候,右儿子全部被选到,然后递归计算左儿子$solve(l, mid, v)$,否则递归计算右儿子。
一次合并需要访问$log$个结点,总时间复杂度$O(nlog^2n)$。
Code:
#include <cstdio>
#include <cstring>
using namespace std;
typedef double db; const int N = 1e5 + ; int n, qn; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline db max(db x, db y) {
return x > y ? x : y;
} namespace SegT {
int res[N << ];
db mx[N << ]; #define lc p << 1
#define rc p << 1 | 1
#define mid ((l + r) >> 1) int solve(int p, int l, int r, db v) {
if(l == r) return (mx[p] > v);
if(mx[lc] <= v) return solve(rc, mid + , r, v);
else return solve(lc, l, mid, v) + res[p] - res[lc];
} void modify(int p, int l, int r, int x, db v) {
if(l == r) {
mx[p] = v;
res[p] = ;
return;
} if(x <= mid) modify(lc, l, mid, x, v);
else modify(rc, mid + , r, x, v); mx[p] = max(mx[lc], mx[rc]);
res[p] = res[lc] + solve(rc, mid + , r, mx[lc]);
} } using namespace SegT; int main() {
read(n), read(qn);
for(int x, v; qn--; ) {
read(x), read(v);
modify(, , n, x, (db)v / x);
printf("%d\n", res[]);
}
return ;
}
Luogu 4198 楼房重建的更多相关文章
- 【题解】Luogu P4198 楼房重建
原题传送门 根据斜率来建线段树,线段树维护区间最大斜率以及区间内能看见的楼房的数量(不考虑其他地方的原因,两个节点合并时再考虑) 细节见程序 #include <bits/stdc++.h> ...
- luogu P4198 楼房重建——线段树
题目大意: 小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线 ...
- [Luogu P4198]楼房重建(线段树)
题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...
- [Luogu] P4198 楼房重建
题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...
- Luogu P4198 楼房重建 (李超线段树)
题目 传送门 题解 首先转化成到(0,0)(0,0)(0,0)的斜率. 那么就是求多少个点是前缀最大值. 做法是线段树,用gao(i,x)gao(i,x)gao(i,x)表示在iii区间内,之前最大值 ...
- Luogu P4198 楼房重建 分块 or 线段树
思路:分块 提交:2次(第一次的求解有问题) 题解: 设块长为$T$,我们开$N/T$个单调栈,维护每一块的上升斜率. 修改时暴力重构整个块,$O(T)$ 求解时记录一个最大斜率$lst$,然后块内二 ...
- 洛谷 P4198 楼房重建 线段树维护单调栈
P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...
- bzoj 2957: 楼房重建 线段树
2957: 楼房重建 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 小A的楼房外有一大片施 ...
- P4198 楼房重建
P4198 楼房重建 集中写博客= = 首先把高度变成斜率 然后就比较玄学了,首先用线段树维护一个区间的斜率最大值,和只看这个区间时能看见的楼房个数ans 然后更新时先更新max,再处理神奇的ans ...
随机推荐
- linux离线搭建Python环境及安装numpy、pandas
1.安装python2.7.3 Cent OS 6.5默认装的有python2.6.6,需要重新安装python2.7.3下载地址:https://www.python.org/downloads/s ...
- 【spring源码学习】Spring的IOC容器之BeanPostProcessor接口学习
一:含义作用 ==>BeanPostProcessor接口是众多Spring提供给开发者的bean生命周期内自定义逻辑拓展接口中的一个 二:接口定义 package org.springfram ...
- elasticsearch snapshot快照备份和恢复
环境:mac 使用brew 安装elasticsearch 1.在 /usr/local/etc/elasticsearch/elasticsearch.yml 文件中配置快照地址 p ...
- python操作RabbitMQ(不错)
一.rabbitmq RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列 ...
- c#联网判断
引用命名空间:sing System.Net.NetworkInformation; var address = "www.baidu.com"; Ping ping = null ...
- JAVA设计模式:静态代理
一.概念代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关 ...
- Kreyos 资料收集
Kreyos 资料收集 使用 默认需要连接 APP 解锁. 固件 https://github.com/kreyosopensource/KreyosFirmware Android 源码 https ...
- bzoj 2865 字符串识别——后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2865 做出 ht[ ] 之后,sa[ ] 上每个位置和它前面与后面取 LCP ,其中较大的长 ...
- GOF23设计模式之建造者模式(builder)
一.建造者模式概述 建造者模式的本质: 1.分离了对象子组件的单独构造(由Builder负责)和装配(由Director负责).从而可以构造出复杂的对象.这个模式适用于:某个对象的过程复杂的情况下使用 ...
- webservice有关application/xop+xml的异常
今天同事调用一个webservice时返回类似错误 响应消息的内容类型 multipart/related; type="application/xop+xml"; boundar ...