luogu P1382 楼房
二次联通门 : luogu P1382 楼房
/*
luogu P1382 楼房 线段树 + 扫描线 + 离散化
正解貌似是堆。。。 MMP。。。二段式线段树各种错误。。。 离散化一下横坐标
扫描线扫一下就好。。 注意判断一个横坐标上对应两个y值的情况。。。
*/
#include <algorithm>
#include <cstdio> #define Max 1000002 void read (int &now)
{
now = ;
bool temp = false;
register char word = getchar ();
while (word < '' || word > '')
{
if (word == '-')
temp = true;
word = getchar ();
}
while (word >= '' && word <= '')
{
now = now * + word - '';
word = getchar ();
}
if (temp)
now = -now;
} inline int min (int _Curs_, int ROcs_)
{
return _Curs_ < ROcs_ ? _Curs_ : ROcs_;
} inline int max (int _Curs_, int ROcs_)
{
return _Curs_ > ROcs_ ? _Curs_ : ROcs_;
} struct Segment_Tree_Data
{
Segment_Tree_Data *Left, *Right; int l, r;
int key;
int Flandre;
int Mid; Segment_Tree_Data ()
{
Left = NULL;
Right = NULL;
key = ;
Flandre = ;
}
}; struct Data_Type
{
int l, r;
int h; bool operator < (const Data_Type &now) const
{
return now.l < l;
}
}; struct Point_Data
{
int x, y;
}; Segment_Tree_Data *Root; class Segment_Tree_Type
{
public : void Build (Segment_Tree_Data *&now, int l, int r)
{
now = new Segment_Tree_Data ();
now->l = l;
now->r = r;
if (l == r)
return ;
now->Mid = l + r >> ; Build (now->Left, l, now->Mid);
Build (now->Right, now->Mid + , r);
} void Change_Section (Segment_Tree_Data *&now, int l, int r, int to)
{
if (l <= now->l && r >= now->r)
{
now->key = max (now->key, to);
now->Flandre = max (now->Flandre, to);
return ;
}
if (now->Flandre)
{
now->Left->key = max (now->Flandre, now->Left->key);
now->Right->key = max (now->Flandre, now->Right->key); now->Left->Flandre = max (now->Flandre, now->Left->Flandre);
now->Right->Flandre = max (now->Flandre, now->Right->Flandre); now->Flandre = ;
}
if (l <= now->Mid)
Change_Section (now->Left, l, min (now->Mid, r), to);
if (r > now->Mid)
Change_Section (now->Right, max (now->Mid + , l), r, to);
now->key = max (now->Left->key, now->Right->key);
} int Query (Segment_Tree_Data *&now, int pos)
{
if (now->l == now->r)
return now->key;
if (now->Flandre)
{
now->Left->key = max (now->Flandre, now->Left->key);
now->Right->key = max (now->Flandre, now->Right->key); now->Left->Flandre = max (now->Flandre, now->Left->Flandre);
now->Right->Flandre = max (now->Flandre, now->Right->Flandre); now->Flandre = ;
}
now->key = max (now->Left->key, now->Right->key);
if (pos <= now->Mid)
return Query (now->Left, pos);
else
return Query (now->Right, pos);
}
}; Segment_Tree_Type Tree; Data_Type data[Max]; int Answer;
int rank[Max << ];
int N;
int Size, Count; Point_Data point[Max]; int main (int argc, char *argv[])
{
read (N);
for (int i = ; i <= N; i++)
{
read (data[i].h);
read (data[i].l);
read (data[i].r);
rank[++Size] = data[i].l;
rank[++Size] = data[i].r;
}
std :: sort (rank + , rank + + Size);
Size = std :: unique (rank + , rank + + Size) - rank - ;
Root = NULL;
Tree.Build (Root, , Size);
for (int i = ; i <= N; i++)
{
data[i].l = std :: lower_bound (rank + , rank + + Size, data[i].l) - rank;
data[i].r = std :: lower_bound (rank + , rank + + Size, data[i].r) - rank;
Tree.Change_Section (Root, data[i].l, data[i].r - , data[i].h);
} for (int i = ; i <= Size; i++)
{
point[i].x = rank[i];
point[i].y = Tree.Query (Root, i);
if (point[i].y != point[i - ].y)
Answer++;
}
printf ("%d\n", Answer << );
for (int i = ; i <= Size; i++)
if (point[i].y != point[i - ].y)
{
printf ("%d %d\n", point[i].x, point[i - ].y);
printf ("%d %d\n", point[i].x, point[i].y);
}
return ;
}
luogu P1382 楼房的更多相关文章
- P1382 楼房
P1382 楼房 每个矩形拆成2个坐标按$x$轴排序,蓝后$multiset$维护最高值. #include<iostream> #include<cstring> #incl ...
- 【题解】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栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...
- P1382 楼房 set用法小结
这个sb题目,剧毒... STL大法好 首先,我准备用经典的线段树优化扫描线来做.之前的矩形周长把我困了数天导致我胸有成竹. 然后,敲代码半小时,调试半个月......这个,sb,怎么改都是0分+2个 ...
- Luogu 4198 楼房重建
BZOJ 2957 挺妙的题. 先把题目中的要求转化为斜率,一个点$(x, y)$可以看成$\frac{y}{x}$,这样子我们要求的就变成了一个区间内一定包含第一个值的最长上升序列. 然后把这个序列 ...
- [洛谷P1382] 楼房
题目描述 地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i]).地平线高度为0.在轮廓 ...
- P1382 楼房 (扫描线,线段树)
题目描述 地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i]).地平线高度为0.在轮廓 ...
随机推荐
- windows 下搭建go开发环境
下载golang安装包: 步骤一: 先打开环境变量配置的界面 步骤二;配置我们的环境变量 对上图的一个说明: 1).path这个变量不需要再创建,因为系统本就有,在后面添加即可. 2).增加Go的bi ...
- Vue.js源码全方位深入解析--学习笔记
模板中的插入变量是如何渲染到DOM上的? initMixin(Vue)->_init->$options-> $mount()当执行该挂载方法时DOM变化 为什么可以通过this访问 ...
- ELK基础配置
前言 近期在研究日志系统的设计,感觉现在公司的子系统和接口太多了,日志看不过来,就想着有没有一种方法可以把各个程序的日志组合到一起.于是乎就搜到了ELK.开始对ELK的概念完全搞不懂,就照着各个平台文 ...
- Arm-Linux 移植 FFMPEG库 + x264
背景: ffmpeg 中带有264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx26 ...
- hdu 3265 第一类斯特林数
先和第二类做一个对比 第一类Stirling数是有正负的,其绝对值是包含n个元素的集合分作k个环排列的方法数目.递推公式为, S(n,0) = 0, S(1,1) = 1. S(n+1,k) = S( ...
- Python之特征工程-3
一.什么是特征工程?其实也是数据处理的一种方式,和前面的原始数据不一样的是,我们在原始数据的基础上面,通过提取有效特征,来预测目标值.而想要更好的去得出结果,包括前面使用的数据处理中数据特征提取,新增 ...
- PyCharm 占用过大 C 盘空间,system 配置文件迁移
随着 PyCharm 的持续使用,对应 C:\Users\<username>\.PyCharm<2018.3> 下的文件大小会持续增大,且通常为 system 文件夹下的内容 ...
- 你听过稀疏数组(sparseArray)吗?
稀疏数组(sparseArray) 基本介绍 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组. 稀疏数组的处理方法是: 1.记录数组一共有几行几列,有多少个不同的值 ...
- nginx代理(正向代理和反向代理)
正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容 ...
- element-ui中使用表单验证的问题
<el-form ref="ruleRules" :inline="true" :model="ruleInfo"> <e ...