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.在轮廓 ...
随机推荐
- [Luogu5324][BJOI2019]删数(线段树)
CF风格题,先猜结论,记数列中i这个数共出现了cnt[i]次,那么所有区间[i-cnt[i]+1,i]的并集的补集大小就是答案. 于是我们只需要线段树维护每个位置是否被某个区间覆盖到即可,对于整体加减 ...
- github的pull request是指什么意思?有什么用处(转)
https://www.cnblogs.com/-walker/p/6093277.html
- Java Comparable与Comparator区别
1,两种接口的展示 下面的程序是两个类各自实现了Comparable接口.Comparator接口 package com.cnblogs.mufasa.Solution; import java.u ...
- Extending WCF using IServiceBehavior, IOperationBehavior, and IParameterInspector
[ServiceContract(Name = "PasswordGenerator")] public interface IPasswordGenerator { [Opera ...
- Java原子操作类汇总(2)
当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...
- Git Git 已被其他开发删除的远程分支,本地依旧显示,如何删除?
- java List<String>的初始化 的一个小问题
今天在处理生成excel的时候用到了java的list,但是需要直接赋值固定的几个变量,如果先初始化然后add的方法: List<String> name = new ArrayList( ...
- 【OF框架】搭建标准工作环境
前言 统一工作环境,统一工具集,是沟通效率的基础.如同语言一样,使用不同语言的人,需要花更多的精力去理解语言,然后才是理解语言的内容,而使用相同语言的人,对话过程直接进入到内容.对于语言不统一增加的效 ...
- html简单代码示例
运行示例: 代码内容如下: <!DOCTYPE html> <html> <head> <title>九九乘法口诀表</title> &l ...
- Codeforces Round #499(Div2) C. Fly (二分精度)
http://codeforces.com/contest/1011/problem/C 题目 这是一道大水题! 仅以此题解作为我这个蒟蒻掉分的见证 #include<iostream> ...