二次联通门 : 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 楼房的更多相关文章

  1. P1382 楼房

    P1382 楼房 每个矩形拆成2个坐标按$x$轴排序,蓝后$multiset$维护最高值. #include<iostream> #include<cstring> #incl ...

  2. 【题解】Luogu P4198 楼房重建

    原题传送门 根据斜率来建线段树,线段树维护区间最大斜率以及区间内能看见的楼房的数量(不考虑其他地方的原因,两个节点合并时再考虑) 细节见程序 #include <bits/stdc++.h> ...

  3. luogu P4198 楼房重建——线段树

    题目大意: 小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线 ...

  4. [Luogu P4198]楼房重建(线段树)

    题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...

  5. [Luogu] P4198 楼房重建

    题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...

  6. P1382 楼房 set用法小结

    这个sb题目,剧毒... STL大法好 首先,我准备用经典的线段树优化扫描线来做.之前的矩形周长把我困了数天导致我胸有成竹. 然后,敲代码半小时,调试半个月......这个,sb,怎么改都是0分+2个 ...

  7. Luogu 4198 楼房重建

    BZOJ 2957 挺妙的题. 先把题目中的要求转化为斜率,一个点$(x, y)$可以看成$\frac{y}{x}$,这样子我们要求的就变成了一个区间内一定包含第一个值的最长上升序列. 然后把这个序列 ...

  8. [洛谷P1382] 楼房

    题目描述 地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i]).地平线高度为0.在轮廓 ...

  9. P1382 楼房 (扫描线,线段树)

    题目描述 地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i]).地平线高度为0.在轮廓 ...

随机推荐

  1. Oracle和SQL Server 用当前日期减去 '0001-01-01' 得出的天数不一致,相差2天,谁知道原因?

    Oracle和SQL Server 用当前日期减去 '0001-01-01' 得出的天数不一致,相差2天.求大佬科普

  2. Spring Boot集成Mybatis完整实例

    步骤: 添加Mybatis依赖: 添加数据库依赖: 配置属性文件: (具体的属性名称可以在jar包中找到) 内容: 建表sql: Mapper文件的头: 集成Mybatis的配置文件中的具体内容可以在 ...

  3. 使用其他身份运行计算机(DOS命令)

    runas/user:administrator cmd d: cd esop sfispri.ini

  4. svn提交时把node_modules忽略掉

    空白处右键>选中TortoiseSVN>设置(settings)>常规设置(General)>Subversion>编辑(edit)>在弹出的config文件中找g ...

  5. CocoaPods - 发布自己的模块(公有库、私有库)

    CocoaPods发布框架到远程公有库 1.编写代码~上传远程仓库 git init git add . git commit -m '提交到本地分支' //关联远程仓库 git remote add ...

  6. cd .ssh返回-bash: cd: .ssh:No such file or directory怎么办

    继续上一篇博文 今天再次陷入同样的问题 避免这个问题的另一个套路是用节点和其他节点直接ssh 远程连接,需要输入密码, 但是输入再次退出之后就OK了 cd 可以到.ssh了  然后就可以开心的免密了

  7. linux7 上安装mongodb4.2.1操作步骤

    MongoDB是一个通用的.基于文档的分布式数据库,它是为现代应用程序开发人员和云时代而构建的.没有数据库能让你更有效率. 1.下载需要的软件包https://www.mongodb.com/down ...

  8. 软件自带依赖库还是共享对象库/为什么linux发行版之间不能有一个统一的二进制软件包标准

    接前文:Linux软件包(源码包和二进制包)及其区别和特点 在前文,我们知道了linux软件包分为源码包和二进制包两种方式,而不同的发行版之间又有着自己的二进制打包格式. 首先,软件运行依赖着各种各样 ...

  9. python中redis

    一.简介 二.redis的安装和使用 三.python操作readis之安装和支持存储类型 四.python操作redis值普通链接 五.python操作redis值连接池 六.操作之String操作 ...

  10. 大数据之路week06--day07(虚拟机的克隆)

    1.安装vmware,务必以管理员身份运行 操作系统(CentOS 6.5)的配置 准备工作:虚拟机安装三台linux  本次测试是 centos 6.5,(三台虚拟机的系统时间保持一致) *安装jd ...