【洛谷】P4198 楼房重建
题解
我们转而维护每个点的斜率,显然一个楼房能被看见它就是一个前缀最大值,斜率比较为了节约精度可以用向量替代
我们每个区间维护被看到的楼房的个数,和楼房的最大值,叶子节点在有楼房时,值为1
那么考虑合并两个区间,左节点的所有能被看到的楼房还是能被看到,右边节点能看到的楼房的斜率需要大于左边节点所需要的斜率最大值
为了找到这些我们去右节点的左右区间去找
如果这个值\(P\)大于等于区间左边的最大值,那么这个值要在右边找
如果小于的话,加上右边的大小,即\(tr[u].cnt - tr[u << 1].cnt\),然后递归到左边处理
复杂度\(O(n \log^2 n)\)
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct Point {
int64 x,y;
Point(int64 _x = 0,int64 _y = 0) {
x = _x;y = _y;
}
friend Point operator + (const Point &a,const Point &b) {
return Point(a.x + b.x,a.y + b.y);
}
friend Point operator - (const Point &a,const Point &b) {
return Point(a.x - b.x,a.y - b.y);
}
friend int64 operator * (const Point &a,const Point &b) {
return a.x * b.y - a.y * b.x;
}
friend bool operator < (const Point &a,const Point &b) {
return a * b > 0;
}
friend bool operator > (const Point &a,const Point &b) {
return a * b < 0;
}
friend bool operator == (const Point &a,const Point &b) {
return a * b == 0;
}
friend bool operator >= (const Point &a,const Point &b) {
return a > b || a == b;
}
friend bool operator <= (const Point &a,const Point &b) {
return a < b || a == b;
}
};
struct node {
int L,R,cnt;Point P;
}tr[MAXN * 4];
int N,M;
void build(int u,int l,int r) {
tr[u].L = l;tr[u].R = r;tr[u].cnt = 0;
tr[u].P = Point(r,0);
if(l == r) return;
int mid = (l + r) >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
}
int Calc(int u,Point P) {
if(tr[u].L == tr[u].R) return tr[u].P > P;
if(P >= tr[u << 1].P) {
return Calc(u << 1 | 1,P);
}
else {
return Calc(u << 1,P) + tr[u].cnt - tr[u << 1].cnt;
}
}
void Change(int u,int pos,int y) {
if(tr[u].L == tr[u].R) {
tr[u].P = Point(pos,y);
if(!y) tr[u].cnt = 0;
else tr[u].cnt = 1;
return;
}
int mid = (tr[u].L + tr[u].R) >> 1;
if(pos <= mid) Change(u << 1,pos,y);
else Change(u << 1 | 1,pos,y);
tr[u].P = max(tr[u << 1].P,tr[u << 1 | 1].P);
tr[u].cnt = tr[u << 1].cnt + Calc(u << 1 | 1,tr[u << 1].P);
}
void Solve() {
read(N);read(M);
build(1,1,N);
int x,y;
for(int i = 1 ; i <= M ; ++i) {
read(x);read(y);
Change(1,x,y);
out(tr[1].cnt);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【洛谷】P4198 楼房重建的更多相关文章
- 洛谷P4198 楼房重建 (分块)
洛谷P4198 楼房重建 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题, ...
- 洛谷 P4198 楼房重建 题解
题面 首先你要知道题问的是什么:使用一种数据结构,动态地维护以1为起点地最长上升子序列(把楼房的高度转化成斜率地序列)的长度: 怎么做?线段树! 我们在线段树上维护两个东西:1.这个区间内斜率的最大值 ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 洛谷P4198 楼房重建(线段树)
题意 题目链接 Sol 别问我为什么发两遍 就是为了骗访问量 这个题的线段树做法,,妙的很 首先一个显然的结论:位置\(i\)能被看到当且仅当\(\frac{H_k}{k} < \frac{H_ ...
- 洛谷P4198 楼房重建
题意:给定序列,每次修改一个值,求前缀最大值的个数. 解:线段树经典应用. 每个节点维护最大值和该区间前缀最大值个数. 发现我们不用下传标记,只需要合并区间. 需要实现一个函数int ask([l r ...
- 洛谷 P4198 楼房重建
思路 此题可转化为以下模型 给定序列\(a[1...n]\),支持单点修改,每次求区间单调栈大小 \(n,Q\le 10^5\) 区间单调栈是什么呢?对于一个区间,建立一个栈,首先将第一个元素入栈,从 ...
- 洛谷 P4198 楼房重建 线段树维护单调栈
P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...
- P4198 楼房重建
P4198 楼房重建 集中写博客= = 首先把高度变成斜率 然后就比较玄学了,首先用线段树维护一个区间的斜率最大值,和只看这个区间时能看见的楼房个数ans 然后更新时先更新max,再处理神奇的ans ...
- 洛谷P1119-灾后重建-floyd算法
洛谷P1119-灾后重建 题目描述 给出\(B\)地区的村庄数NN,村庄编号从\(0\)到\(N-1\),和所有\(M\)条公路的长度,公路是双向的. 给出第\(i\)个村庄重建完成的时间\(t_i\ ...
- 洛谷 P3905 道路重建
题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...
随机推荐
- c# 移除文本文件里的某一行
参考自:http://zhidao.baidu.com/question/87467507.html //定义一个变量用来存读到的东西 string text = ""; //用一 ...
- 【bzoj1089】严格n元树
Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严格 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- $.AJAX参数提交及后台获取方式
$.AJAX默认是get方式提交,所以你在后台只能用获取url参数的方式获取,可指定type为post更改提交方式: 在后台可通过Request["控件name/url参数key" ...
- gtest简介及简单使用
本文摘自 gtest简介及简单使用 ,在此感谢作者的分享. 具体使用教程 _______________________________________________________________ ...
- json字符串转java对象
今天遇到一个问题,前端ajax获取到一个javaBean对象,好多方法发ajax请求需要把这个对象再传到后端,后端再根据这个对象进行操作(之前计划传递id,但发现传递id的话,后端多个方法都需要根据i ...
- python---补充django中文报错(2),Django3.5出错
今天是要Django3.5设置项目,结果出现中文报错,虽然之前分析过py2.7的报错原因,但是在py3之后reload不在使用,需要引入: from importlib import reload 但 ...
- RabbitMQ入门介绍
1.关于AMQP协议 AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设 ...
- 【DS】排序算法之快速排序(Quick Sort)
一.算法思想 快速排序,顾名思义,效率比较于其他算法,效率比较高.<算法导论>也专门对其进行讲解.其算法设计使用分治思想,如下: 1)从数组A[p...r]中选择一个元素,将数组划分成两个 ...
- bzoj千题计划188:bzoj1923: [Sdoi2010]外星千足虫 (高斯—若尔当消元法解异或方程组)
http://www.lydsy.com/JudgeOnline/problem.php?id=1923 #include<cstdio> #include<cstring> ...