【题目描述】:在地平线上有n个建筑物。每个建筑物在地平线上可以看成一个下边界和地平线重合的矩形。每个建筑物有三个描述(Li ,Ri,Hi),分别表示该建筑物的左边界,右边界,高度。输出输出这些建筑物在地平线上投影的总面积。

【输入文件】

输入文件horizon.in第一行包含一个整数n,表示有n个建筑物。

以下下n.行,每行三个整数Li ,Ri,Hi。

【输出文件】

输出这些建筑物在地平线上投影的总面积

【样例】

horizon.in   horizon.out   4

2 5 1

9 10 4

6 8 2

4 6 3

16

【限制】

100%的数据满足:1<=n<=40,000

1 ≤ Li < Ri ≤ 1,000,000,000

1 ≤ Hi ≤ 1,000,000,000

区间问题容易想到线段树解决。最开始想枚举每个区间最左和最右两个矩形的位置关系(相离、相切、相交、内含)并在建树时即统计面积,但在写的发现很难实现…

正解是区间修改,每加入一个矩形,就二分找到它所覆盖的区间,并改变该区间的覆盖高度

在建树时注意因为矩形边长>=1,右界需要取中点,且叶子节点的左右端点相差为1;

此题的考点:

1、区间中需要处理的点稀疏而区间很长时,需要离散化(矩形的端点只有80000个,区间长10亿);

2、区间修改操作;

#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int ans,t;
struct node{
int left,right;
int c;
}tree[*];
struct edge{
int left,right,h;
}a[];
int p[*];
bool cmp(edge e1,edge e2)
{
return e1.h<e2.h;
}
int erfen(int l,int r,int x)
{
while(l<=r)
{
int mid=(l+r)/;
if(p[mid]==x) return mid;
else if(p[mid]>x) r=mid-;
else l=mid+;
}
return ;
}
void change(int now,int l,int r,int x)
{
if(tree[now].right<l||tree[now].left>r) return;
if(tree[now].left>=l&&tree[now].right<=r)
{
tree[now].c=x;
return;
}
int mid=(tree[now].left+tree[now].right)/;
if(tree[now].c) {
tree[now*].c=tree[now].c;
tree[now*+].c=tree[now].c;
tree[now].c=;
} if(mid>=r) change(now*,l,r,x);
else if(mid<=l) change(now*+,l,r,x);
else {
change(now*,l,r,x); change(now*+,l,r,x);
}
}
void built(int now,int l,int r)
{
tree[now].left=l;
tree[now].right=r;
tree[now].c=;
if(l==r-) return;
built(now*,l,(l+r)/);
built(now*+,(l+r)/,r);//*****右界要包括mid
}
void quest(int now)
{
if(tree[now].c)
{
ans+=(p[tree[now].right]-p[tree[now].left])*tree[now].c;
return;
}
if(tree[now].right==tree[now].left+) return;
quest(now*);
quest(now*+);
}
int main()
{
freopen("horizon.in","r",stdin);
freopen("horizon.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&a[i].left,&a[i].right,&a[i].h);
p[++t]=a[i].left;
p[++t]=a[i].right;
}
sort(p+,p++*n);
sort(a+,a+n+,cmp);
built(,,n*);
for(int i=;i<=n;i++)
{
int l=erfen(,*n,a[i].left);
int r=erfen(,*n,a[i].right);
change(,l,r,a[i].h);
}
quest();
printf("%d",ans);
}

| 线段树-地平线horizon的更多相关文章

  1. 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树

    [BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...

  2. 【BZOJ】1645: [Usaco2007 Open]City Horizon 城市地平线(线段树+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1645 这题的方法很奇妙啊...一开始我打了一个“离散”后的线段树.............果然爆了. ...

  3. bzoj 1645: [Usaco2007 Open]City Horizon 城市地平线【线段树+hash】

    bzoj题面什么鬼啊-- 题目大意:有一个初始值均为0的数列,n次操作,每次将数列(ai,bi-1)这个区间中的数与ci取max,问n次后元素和 离散化,然后建立线段树,每次修改在区间上打max标记即 ...

  4. [BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 线段树

    链接 题意:N个矩形块,交求面积并. 题解 显然对于每个 \(x\),只要求出这个 \(x\) 上面最高的矩形的高度,即最大值 将矩形宽度离散化一下,高度从小到大排序,线段树区间set,然后求和即可 ...

  5. 离散化+线段树 POJ 3277 City Horizon

    POJ 3277 City Horizon Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18466 Accepted: 507 ...

  6. poj City Horizon (线段树+二分离散)

    http://poj.org/problem?id=3277 City Horizon Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

  7. 线段树 扫描线 L - Atlantis HDU - 1542 M - City Horizon POJ - 3277 N - Paint the Wall HDU - 1543

    学习博客推荐——线段树+扫描线(有关扫描线的理解) 我觉得要注意的几点 1 我的模板线段树的叶子节点存的都是 x[L]~x[L+1] 2 如果没有必要这个lazy 标志是可以不下传的 也就省了一个pu ...

  8. [POJ] 3277 .City Horizon(离散+线段树)

    来自这两篇博客的总结 http://blog.csdn.net/SunnyYoona/article/details/43938355 http://m.blog.csdn.net/blog/mr_z ...

  9. POJ 3277 City Horizon(叶子节点为[a,a+1)的线段树+离散化)

    网上还有用unique函数和lowerbound函数离散的方法,可以百度搜下题解就有. 这里给出介绍unique函数的链接:http://www.cnblogs.com/zhangshu/archiv ...

随机推荐

  1. volative 与处理器的嗅探技术

    在<java并发编程的艺术>这本书中,关于volatile的内存原理本质的描述如下: 有volatile变量修饰共享变量在编译器编译后,后多出一个“lock” 来(lock前缀指令相当于一 ...

  2. java(8)二重循环

    一.二重循环 1.循环中,嵌套另外一个循环,将内层的循环,看成外层循环的一个循环操作 2.常见的二重循环 形式1:      外层while或do…while 内层为for循环 形式2: 外层.内层都 ...

  3. 非极大值抑制(NMS)

    转自:https://www.cnblogs.com/makefile/p/nms.html 概述 非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的 ...

  4. MySQL学习9 - 单表查询

    一.单表查询的语法 二.关键字的执行优先级(重点) 三.单表查询示例 1.where约束 2.group by分组查询 3.聚合函数 4.HAVING过滤 5.order by查询排序 6.limit ...

  5. Jenkins--发送邮件配置

    使用Jenkins可以进行构建,并可以发送邮件.今天我们来讲一下邮件的配置. 首先:下载安装插件: 进入[Jenkins-系统管理-插件管理-可选插件],搜索“Email Extension”进行安装 ...

  6. 第三章Android移植平台工具介绍

    第三章Android移植平台工具介绍 进行 Android 移植的学习并不一定需要一款 Android 手机,但必须要有一款主流的开发板,开发板是用来进行嵌入式系统开发的电路板,包括中央处理器.存储器 ...

  7. C# - 多线程(基础)

    多线程 基础(Multithreading) 一些基本的关于线程和与其相关的概念 位)的变量赋值,这个操作就是原子性的.因为它可以一次性填充64位的二进制数据到栈上,属于一步完成,不会发生断裂.而假如 ...

  8. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  9. SQL入门(4): 嵌入式SQL语言

    本节讲述内容: 1.嵌入式SQL 语言概述 2.变量声明与数据库连接 3.数据集与游标 4.可滚动游标与数据库的增删改 5.状态捕捉以及错误处理机制 (一)嵌入式SQL语言 之前我们所学的都是交互式S ...

  10. STM32串口空闲中断

    串口初始化 #include "usart5.h" vu16 UART5_RX_STA=0; char UART5_RX_BUF[UART5_REC_LEN]; u8 UART5_ ...