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.在轮廓 ...
随机推荐
- 【转载】Maven入门实践
Maven 确确实实是个好东西,用来管理项目显得很方便,但是如果是通过 Maven 来远程下载 JAR 包的话,我宿舍的带宽是4兆的,4个人共用,有时候用 Maven 来远程下载 JAR 包会显得很慢 ...
- CentOS7+Docker+MangoDB下部署简单的MongoDB分片集群
简单的在Docker上快速部署MongoDB分片集群 前言 文中使用的环境如下 OS:CentOS Linux release 7.5.1804 (Core) Docker:Docker versio ...
- hdu 6562 Lovers (线段树)
大意: 有$n$个数字串, 初始为空, 两种操作(1)把$[l,r]$范围的所有数字串首位添加数位$d$ (2)询问$[l,r]$区间和 假设添加的数为$L$, $L$位数为$H$, $L$翻转后乘上 ...
- 怎么将visual studio项目打包生成dll文件
1.打开电脑再打开visual studio软件,在软件里面新建一个项目,文件---->新建---->项目,打开新建项目窗口. 2.选择C#类工程,并为项目命名. 3.将类库文件class ...
- 使用docker搭建reids主从,哨兵。
Redis主从配置,如果没有真机就要用虚拟机,使用Docke for Windows host网络有问题. 准备: 1.安装虚拟机. 2.下载redis的安装文件:http://download.re ...
- 3_PHP表达式_5_数据类型转换_类型强制转换
以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. PHP类型转换分为类型自动转换和类型强制转换. 3.5.2 类型强制转换 类型强制转换允许编程人员手动将变量的数据 ...
- html+css+javascript网页制作技巧总结1
(一)div.元素居中中显示方法: 1.宽度要有实际值或百分比值 2.margin:0px auto; 文本内容居中显示的方法: 1.text-align:center; 2.line-height: ...
- MySQL 启动、登录、退出和目录结构
一.启动 MySQL 服务器启动方式有两种: (1)通过服务的方式自动启动 (2)手动启动的方式 1.windows 服务方式启动 操作步骤: 也可以在 cmd 窗口 输入 services.msc ...
- Python查找电话号码归属地、邮编、运营商信息等
# -*- coding: utf-8 -*- 1. 查找单个电话号码 from phone import Phone def get_phone_info(phone_num): phone_inf ...
- jar命令详解
原文链接:https://www.cnblogs.com/anyehome/p/9435371.html JAR包是Java中所特有一种压缩文档,其实大家就可以把它理解为.zip包.当然也是有区别的, ...