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.在轮廓 ...
随机推荐
- Docker学习笔记导航帖
1. Docker安装 安装docker https://www.cnblogs.com/kreo/p/10813010.html
- VS.NET(C#)--2.8_CCS样式
CSS样式 文件命名 StyleSheet.css body { font-size:12px } .button { color:Red; text-decoration:none; ...
- vue基础部分
一 vue概念 是一个构建用户界面的javascript框架 二 如何使用vue 1. 导入vue.js文件 2. 展示HTML 3. 建立vue对象,写JavaScript代码 vue的简单实用:申 ...
- 步步截图的SMM框架入门实战指引(SpringBoot、Mybatis Plus、Maven)
前提是对spring.springmvc.mybatis有初步学习和理解,因为要全部讲这些框架的知识点太多了,自己学习,这里是实战示范(大部分人学了知识之后去实战会出现很多问题,所以出此教程) 开发环 ...
- Mac 下编译 Hadoop
Mac 下编译 Hadoop-2.9.2 系统环境 系统: Mac OS_10.14.4 maven: Apache Maven 3.6.0 jdk: jdk_1.8.0_201 ProtocolBu ...
- Ext之页面多次请求问题(下拉框发送无关请求)
extjs 下拉框在拉取本地数据,然后又要展示后台数据时,出现过此问题(加载页面,自动发送无关的请求导致后台出现错误日志) { xtype:'combo', id:'state', width:130 ...
- 模板、中间件以及MVC与MTV
模板 基本数据类型的渲染 {#基础数据类型的渲染#} {#1. 变量#} {{ name }} {#2. 列表#} {#通过点索引可以取值#} {{ list.0 }} {#for循环取值#} {% ...
- springcloud 之Ribbon客户端负载均衡配置使用
pom.xml添加配置说明:这里服务注册与发现用的是Eureka,所以消费者端需要引入eureka,使用EurekaClient来调用服务 <dependency> <groupId ...
- Oracle数据的导入与导出
本文针对window操作系统与oracle12C的版本. 1.sqlplus执行单个sql文件 1.执行sqlplus登陆命令:sqlplus username/password@host:port/ ...
- Android笔记(二十七) Android中的动态广播和静态广播
广播接收器注册一共有两种形式 : 静态注册和动态注册. 两者及其接收广播的区别: 1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低>\ ...