洛谷 P4198 楼房重建 题解
首先你要知道题问的是什么:
使用一种数据结构,动态地维护以1为起点地最长上升子序列(把楼房的高度转化成斜率地序列)的长度;
怎么做?线段树!
我们在线段树上维护两个东西:1.这个区间内斜率的最大值 2.从这段区间开头可以看到的区间内的所有楼房
初始化:
对于每一个叶子节点,从这段区间头可以看到的楼房数量一定为1,区间斜率最大值一定为该点的斜率;
在合并时:
1.我们可以先查找右区间的左区间的最大值,如果右区间的左区间的最大值比左区间的最大值小,那么右区间的左区间的所有答案一定看不到,所以我们就可以递归查找右区间的右区间
2.如果右区间的左区间的最大值比左区间的最大值大,那么原来被右区间的左区间挡住的现在一样会被挡住,我们就可以加上右区间的右区间的答案,所以我们可以递归查找右区间的左区间
时间复杂度是O(nlog^2n);
#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
class segment{
public:
class node{
public:
double maxn;
int tot;
}tree[2000010];
int query(int k,int l,int r,double goal){
if(tree[k].maxn<=goal){
return 0;
}
if(l==r){
return tree[k].maxn>goal;
}
int mid=(l+r)/2;
if(tree[k<<1].maxn<=goal){
return query(k<<1|1,mid+1,r,goal);
}
else{
return query(k<<1,l,mid,goal)+tree[k].tot-tree[k<<1].tot;
}
}
void change(int k,int l,int r,int goal,double value){
if(l==goal&&r==goal){
tree[k].maxn=value;
tree[k].tot=1;
return;
}
int mid=(l+r)/2;
if(goal<=mid) change(k<<1,l,mid,goal,value);
else change(k<<1|1,mid+1,r,goal,value);
tree[k].maxn=max(tree[k<<1].maxn,tree[k<<1|1].maxn);
tree[k].tot=tree[k<<1].tot+query(k<<1|1,mid+1,r,tree[k<<1].maxn);
}
}SEG;
int n,m;
template<class nT>
inline void read(nT& x){
char c;
while(c=getchar(),!isdigit(c));
x=c^48;
while(c=getchar(),isdigit(c)) x=x*10+c-48;
}
int main()
{
read(n); read(m);
inc(i,1,m){
int x,y;
read(x); read(y);
SEG.change(1,1,n,x,(double)y/x);
printf("%d\n",SEG.tree[1].tot);
}
}
洛谷 P4198 楼房重建 题解的更多相关文章
- 洛谷P4198 楼房重建 (分块)
洛谷P4198 楼房重建 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题, ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 洛谷P4198 楼房重建(线段树)
题意 题目链接 Sol 别问我为什么发两遍 就是为了骗访问量 这个题的线段树做法,,妙的很 首先一个显然的结论:位置\(i\)能被看到当且仅当\(\frac{H_k}{k} < \frac{H_ ...
- 洛谷P4198 楼房重建
题意:给定序列,每次修改一个值,求前缀最大值的个数. 解:线段树经典应用. 每个节点维护最大值和该区间前缀最大值个数. 发现我们不用下传标记,只需要合并区间. 需要实现一个函数int ask([l r ...
- 洛谷 P4198 楼房重建
思路 此题可转化为以下模型 给定序列\(a[1...n]\),支持单点修改,每次求区间单调栈大小 \(n,Q\le 10^5\) 区间单调栈是什么呢?对于一个区间,建立一个栈,首先将第一个元素入栈,从 ...
- 洛谷 P3905 道路重建 题解
P3905 道路重建 题目描述 从前,在一个王国中,在\(n\)个城市间有\(m\)条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有\(d\)条道路被破坏了.国王想 ...
- 洛谷 P4198 楼房重建 线段树维护单调栈
P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...
- 洛谷P1119-灾后重建-floyd算法
洛谷P1119-灾后重建 题目描述 给出\(B\)地区的村庄数NN,村庄编号从\(0\)到\(N-1\),和所有\(M\)条公路的长度,公路是双向的. 给出第\(i\)个村庄重建完成的时间\(t_i\ ...
- 洛谷P2832 行路难 分析+题解代码【玄学最短路】
洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...
随机推荐
- Codeforces 678E. Another Sith Tournament(概率DP,状压)
Codeforces 678E. Another Sith Tournament 题意: n(n<=18)个人打擂台赛,给定任意两人对决的胜负概率,比赛规则:可指定一人作为最开始的擂主,每次可指 ...
- 图论——Floyd算法拓展及其动规本质
一.Floyd算法本质 首先,关于Floyd算法: Floyd-Warshall算法是一种在具有正或负边缘权重(但没有负周期)的加权图中找到最短路径的算法.算法的单个执行将找到所有顶点对之间的最短路径 ...
- 17.树的子结构 Java
题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 思路 双递归:外层HasSubtree是一个先根遍历递归,内层isDirectSubTree是一个 ...
- js 继承的一个例子
<script type="text/javascript"> function Animal(){ this.species = "动物"; th ...
- Java-CAS 与原子类
CAS(Compare and Swap),即比较并替换,实现并发算法时常用到的一种技术. CAS 的思想很简单:三个参数,一个当前内存值 V.旧的预期值 A.即将更新的值 B,当且仅当预期值 A 和 ...
- koa 项目打包(使用webpack打包koa2 框架app)
关键问题 一:所有node_modules里的模块都不进行打包 webpack的核心功能是将引用的各个模块打到一个文件里,并会将各种规范的模块进行统一的模块化处理(webpack规范). 然而node ...
- 【JDBC】使用Spring提供的JDBCTemplate通过Statement向MySql数据库插入千万条数据,耗时4m55s,使用insert语句批量插入方式二
这回依然是使用 insert批量插入这种方式 insert into emp(name,age,cdate) values ('A' , 20, '2019-10-13 00:00:00'), ('B ...
- AS中集成bug管理系统
这里大家可以选择各种Bug管理工具,几乎包括了市面上常用的各种Bug跟踪管理工具. 由于如:点击JIRA,填入公司JIRA服务器的地址,填入Server.Username和密码即可,点击Test,弹出 ...
- [CDH] Cloudera's Distribution including Apache Hadoop
You may choose to install spark, yarn, hive, etc one by one. [Spark] 00 - Install Hadoop & Spark ...
- 堡垒机直接调用RUN
两个脚本 Run.vbe 参考https://blog.csdn.net/skypeGNU/article/details/12708221 set ws=wscript.createobject ...