【题目描述】:在地平线上有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. Blender 2.78 突然卡顿

    之前一直好好的直到这两天打开就一直延迟半拍,重启重装无效. 解决方法: NVIDIA控制面板→管理3d设置→程序设置→选择blender,更改显卡为集成显卡→应用 亲测有效.

  2. 获取多<a/>标签id值的点击事件

    <li> <div class="pic"> <c:if test="${userId != null }"> <a ...

  3. python跨网段遍历枚举IP地址(转)

    转载链接:https://blog.csdn.net/u013042248/article/details/53165508 0x01 代码思路: 利用二进制遍历: 1.将IP地址分割,每一块转换为8 ...

  4. MySql常见约束

    含义:一种限制,用于限制表中的数据,为了保证表中数据的准确性和可靠性. 分类:六大约束 1.NOT NULL :非空,用于保证该字段的值不能为空.例如学生表的学生姓名及学号等等. 2.DEFAULT: ...

  5. python学习第22天

    封装 properpty classmathod staticmathod

  6. AngularJS初识

     AngularJS 简介 AngularJS是一个javaScript框架,是一个用JavaScript编写的库,通过指令扩展了HTML,且通过表达式绑定数据到HTML中. AngularJS使开发 ...

  7. udp/tcp流程

    udp: 1.创建套接字 socket 2.绑定本地ip/port bind 3.收发数据 sendto/recvfrom 4.关闭套接字 close tcp客户端: 1.创建套接字 socket 2 ...

  8. C# 微信开发-----微信会员卡(三)激活会员卡

    在会员领取了会员卡之后需要做 一个跳转性激活,模式请看下图: 在创建会员卡的时候需要配置下这个参数的值: memberActivate.aspx页面代码如下: <%@ Page Language ...

  9. redis-list操作

    List操作,redis中的List在在内存中按照一个name对应一个List来存储.如图: lpush(name,values) # 在name对应的list中添加元素,每个新的元素都添加到列表的最 ...

  10. 阿里云centos7成功安装和启动nginx,但是外网访问不了的解决方案

    问题环境: 阿里云centos7.4.1708 问题描述:成功配置,启动成功,外网访问不了 解决方案: 经过查阅文档,去阿里云后台查看,原来是新购的服务器都加入和实例安全组. (OMG)立即去配置.加 ...