题目描述

Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and observe the beautiful silhouettes formed by the rectangular buildings.

The entire horizon is represented by a number line with N (1 ≤ N ≤ 40,000) buildings. Building i's silhouette has a base that spans locations Ai through Bi along the horizon (1 ≤ Ai < Bi ≤ 1,000,000,000) and has height Hi (1 ≤ Hi ≤ 1,000,000,000). Determine the area, in square units, of the aggregate silhouette formed by all N buildings.

约翰带着奶牛去都市观光。在落日的余晖里,他们看到了一幢接一幢的摩天高楼的轮廓在地平线 上形成美丽的图案。以地平线为 X 轴,每幢高楼的轮廓是一个位于地平线上的矩形,彼此间可能有 重叠的部分。奶牛一共看到了 N 幢高楼,第 i 幢楼的高度是 Hi,两条边界轮廓在地平线上的坐标是 Ai 到 Bi。请帮助奶牛们计算一下,所有摩天高楼的轮廓覆盖的总面积是多少。

输入输出格式

输入格式

第一行一个整数N,然后有N行,每行三个正整数ai、bi、Hi。

输出格式

一个数,数列中所有元素的和。

样例

INPUT

4

2 5 1

9 10 4

6 8 2

4 6 3

OUTPUT

16

HINT

N<=40000 , a、b、k<=10^9 。

SOLUTION

离散化+线段树

瞄一眼数据范围,不用想就知道一定要离散化,对于我来说这种离散化方法还是头一次用(就是这离散化调得我大头疼。)然后区间最大值?果断线段树啊。

其实对于题目给定的\(a_i,b_i\)画个图就可以看出来,由于我们线段树处理的是点,所以我们只要覆盖\(a_i\)到\(b_i-1\)的点就行了。

而且因为对于每一段区间我们保留的是最大的\(h\),所以只要再修改以前,以\(h\)为关键字,再对每栋楼从小到大排个序就可以直接覆盖了。

如何计算呢?

因为我们离散化之后就剩下了一堆关键点\(p\),然后对于每一个\(p_i\)只要把\(i\)点的高度乘以\((p_{i+1}-p_i)\)(前面有说,因为不包括右端点)就可以得到面积了。

然后记得push_down的时候一定要先判断\(s[id]\)是否非零,不然就把原来存在的值清除了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=40100;
int n,p[N<<1],s[N<<3];
LL ans=0;
struct BD{int a,b,h;}bld[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-48;ch=getchar();}
return x*f;}
bool cmp(BD x,BD y) {return x.h<y.h;}
void pushdown(int id,int l,int r){
if (l==r) return;
s[id<<1]=s[id];s[id<<1|1]=s[id];s[id]=0;}
void change(int id,int l,int r,int L,int R,int H){
if (s[id]) pushdown(id,l,r);
if (l>=L&&r<=R) {s[id]=H;return;}
int mid=(l+r)>>1;
if (mid>=L) change(id<<1,l,mid,L,R,H);
if (mid<R) change(id<<1|1,mid+1,r,L,R,H);
}
int findh(int id,int l,int r,int ND){
if (l==r) {return s[id];}
if (s[id]) pushdown(id,l,r);
int mid=(l+r)>>1;
if (mid>=ND) return findh(id<<1,l,mid,ND);
else return findh(id<<1|1,mid+1,r,ND);
}
int main(){
int i,j;
n=read();for (i=1;i<=n;++i) {
bld[i].a=read();bld[i].b=read();bld[i].h=read();
p[i*2-1]=bld[i].a;p[i*2]=bld[i].b;}
sort(p+1,p+1+2*n);
int cnt=2*n;//int cnt=unique(p+1,p+1+2*n)-p;
sort(bld+1,bld+1+n,cmp);
memset(s,0,sizeof(s));
for (i=1;i<=n;++i){
int L=lower_bound(p+1,p+1+cnt,bld[i].a)-p;
int R=lower_bound(p+1,p+1+cnt,bld[i].b)-p;
// printf("L:%d R:%d H:%d\n",L,R-1,bld[i].h);
change(1,1,cnt,L,R-1,bld[i].h);
}
for (i=1;i<cnt;++i){
LL H=findh(1,1,cnt,i);
ans=ans+H*(p[i+1]-p[i]);
// printf("%lld %d;",H,(p[i+1]-p[i]));
// printf("%d %d\n",p[i],p[i+1]);
}
printf("%lld\n",ans);
return 0;
}

Luogu_2061_[USACO07OPEN]城市的地平线City Horizon的更多相关文章

  1. bzoj1645 / P2061 [USACO07OPEN]城市的地平线City Horizon(扫描线)

    P2061 [USACO07OPEN]城市的地平线City Horizon 扫描线 扫描线简化版 流程(本题为例): 把一个矩形用两条线段(底端点的坐标,向上长度,添加$or$删除)表示,按横坐标排序 ...

  2. 线段树+扫描线【bzoj1645】[USACO07OPEN]城市的地平线City Horizon

    Description 约翰带着奶牛去都市观光.在落日的余晖里,他们看到了一幢接一幢的摩天高楼的轮廓在地平线 上形成美丽的图案.以地平线为 X 轴,每幢高楼的轮廓是一个位于地平线上的矩形,彼此间可能有 ...

  3. [题目] luogu P2061 [USACO07OPEN]城市的地平线City Horizon

    算法 线段树 + 离散化 思路 对\((x,y,h)\)的左右端点\(x,y\)进行离散化,离散化前的原值记为\(val[i]\),对每个矩形按高度\(h\)从小到大排序. 设离散化后的端点有\(M\ ...

  4. 洛谷 P2061 [USACO07OPEN]城市的地平线City Horizon

    简化版的矩形面积并,不用线段树,不用离散化,代码意外的简单 扫描线,这里的基本思路就是把要求的图形竖着切几刀分成许多矩形,求面积并.(切法就是每出现一条与y轴平行的线段都切一刀) 对于每一个切出来的矩 ...

  5. 1645: [Usaco2007 Open]City Horizon 城市地平线

    1645: [Usaco2007 Open]City Horizon 城市地平线 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 315  Solved: ...

  6. BZOJ_1654_[Usaco2007 Open]City Horizon 城市地平线_扫描线

    BZOJ_1654_[Usaco2007 Open]City Horizon 城市地平线_扫描线 Description N个矩形块,交求面积并. Input * Line 1: A single i ...

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

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

  8. bzoj1645 [Usaco2007 Open]City Horizon 城市地平线

    Description Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at ...

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

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

随机推荐

  1. php抓取网站图片源码

    <?php /*完成网页内容捕获功能*/ function get_img_url($site_name){     $site_fd = fopen($site_name, "r&q ...

  2. 基于serverless快速部署前端项目到腾讯云

    腾讯云 COS 组件,可以快速部署静态网站页面到对象存储 COS 中,并生成域名供访问. 安装 首先要安装 serverless 组件 npm install -g serverless 在项目的根目 ...

  3. vuex的优缺点

    vuex的优点 1.解决了非父子组件的消息传递(将数据存放在state中) 2.减少了AJAX请求次数,有些情景可以直接从内存中的state获取 vuex的缺点 1.刷新浏览器,vuex中的state ...

  4. eclipse创建文件携带作者时间

    windows–>preference Java–>Code Style–>Code Templates code–>new Java files 编辑它 ${filecomm ...

  5. 微信H5支付demo

    首先我们必须得在微信公众平台和微信商业平台那边配置好相关配置 1.注册微信服务号,开通微信支付权限绑定微信商业平台(这个具体怎么操作我就不说了) 2.获取应用(公众号)appid.应用(公众号)秘钥. ...

  6. CodeForces 992B Nastya Studies Informatics + Hankson的趣味题(gcd、lcm)

    http://codeforces.com/problemset/problem/992/B  题意: 给你区间[l,r]和x,y 问你区间中有多少个数对 (a,b) 使得 gcd(a,b)=x lc ...

  7. 理解python的可变参数

    以 str.format(*args,**kwargs) 为例. "type1:{},{},{},{}_type2:{a},{b},{c},{d}".format('a',2,*[ ...

  8. 大数据学习——MapReduce学习——字符统计WordCount

    操作背景 jdk的版本为1.8以上 ubuntu12 hadoop2.5伪分布 安装 Hadoop-Eclipse-Plugin 要在 Eclipse 上编译和运行 MapReduce 程序,需要安装 ...

  9. 解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题

    WinForm 启动时隐藏窗体最简单有效的办法是重写 CreateParams protected override CreateParams CreateParams { get { base.Vi ...

  10. GPIO口的脚本配置之——全志H3script.bin

    此脚本的作用之一是配置GPIO的默认状态: 如:功能,内部电阻状态,驱动能力等. 1.但是直接打开script.bin 文件则会出现乱码,那么我们怎么才可以打开并更改该脚本的配置呢? 在路径uboot ...