博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树
阅读量:5143 次
发布时间:2019-06-13

本文共 2788 字,大约阅读时间需要 9 分钟。

【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 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 A_i through B_i along the horizon (1 <= A_i < B_i <= 1,000,000,000) and has height H_i (1 <= H_i <= 1,000,000,000). Determine the area, in square units, of the aggregate silhouette formed by all N buildings.

N个矩形块,交求面积并.

Input

* Line 1: A single integer: N

* Lines 2..N+1: Input line i+1 describes building i with three space-separated integers: A_i, B_i, and H_i

Output

* Line 1: The total area, in square units, of the silhouettes formed by all N buildings

Sample Input

4
2 5 1
9 10 4
6 8 2
4 6 3

Sample Output

16
OUTPUT DETAILS:
The first building overlaps with the fourth building for an area of 1
square unit, so the total area is just 3*1 + 1*4 + 2*2 + 2*3 - 1 = 16.

题解:一看就是离散化+线段树的题,可以先将h离散,再按a,b排序,用线段树维护扫描线来做,不过这样比较麻烦。

因为本题中所有的矩形底边都在同一直线上,所以我们可以把这些矩形整体看成一棵线段树,线段树的区间就是每个a,b,线段树的权值就是h,然后按h排序,从小到大一个一个加到线段树里就行了。

注意:a和b离散化后是2*40000的空间,所以线段树要开8*40000!2*4==8!!!

#include 
#include
#include
#include
#define lson x<<1#define rson x<<1|1using namespace std;const int maxn=40010;typedef long long ll;struct edges{ ll pos,org;}s[maxn<<1];struct house{ ll sa,sb,sh;}p[maxn];int n,m;ll ts[maxn<<3],tag[maxn<<3],ref[maxn<<1];bool cmp1(edges a,edges b){ return a.pos
>1; ts[lson]=(ref[mid]-ref[l])*tag[x],ts[rson]=(ref[r]-ref[mid])*tag[x]; tag[lson]=tag[rson]=tag[x]; tag[x]=0; }}void pushup(int x){ ts[x]=ts[lson]+ts[rson];}void updata(int l,int r,int x,int a,int b,ll v){ if(a<=l&&r<=b) { ts[x]=(ref[r]-ref[l])*v; tag[x]=v; return ; } pushdown(l,r,x); int mid=l+r>>1; if(b<=mid) updata(l,mid,lson,a,b,v); else if(a>=mid) updata(mid,r,rson,a,b,v); else updata(l,mid,lson,a,b,v),updata(mid,r,rson,a,b,v); pushup(x);}int main(){ scanf("%d",&n); int i; for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&p[i].sa,&p[i].sb,&p[i].sh); s[i*2-1].pos=p[i].sa,s[i*2].pos=p[i].sb; s[i*2-1].org=s[i*2].org=i; } sort(s+1,s+2*n+1,cmp1); for(i=1;i<=2*n;i++) { if(s[i].pos>ref[m]) ref[++m]=s[i].pos; if(s[i].pos==p[s[i].org].sa) p[s[i].org].sa=m; else p[s[i].org].sb=m; } sort(p+1,p+n+1,cmp2); for(i=1;i<=n;i++) updata(1,m,1,p[i].sa,p[i].sb,p[i].sh); printf("%lld",ts[1]); return 0;}

 

转载于:https://www.cnblogs.com/CQzhangyu/p/6281746.html

你可能感兴趣的文章
第23月第24天 git命令 .git-credentials git rm --cached git stash clear
查看>>
java SE :标准输入/输出
查看>>
[ JAVA编程 ] double类型计算精度丢失问题及解决方法
查看>>
好玩的-记最近玩的几个经典ipad ios游戏
查看>>
tmux的简单快捷键
查看>>
[Swift]LeetCode922.按奇偶排序数组 II | Sort Array By Parity II
查看>>
Vue_(组件通讯)子组件向父组件传值
查看>>
移动开发平台-应用之星app制作教程
查看>>
DataGridView的行的字体颜色变化
查看>>
[Serializable]的应用--注册码的生成,加密和验证
查看>>
LeetCode【709. 转换成小写字母】
查看>>
如果没有按照正常的先装iis后装.net的顺序,可以使用此命令重新注册一下:
查看>>
【题解】青蛙的约会
查看>>
Android 官方新手指导教程
查看>>
幸运转盘v1.0 【附视频】我的Android原创处女作,请支持!
查看>>
安装 Express
查看>>
Weka中数据挖掘与机器学习系列之基本概念(三)
查看>>
leetcode-Sort List
查看>>
中文词频统计
查看>>
Postman-----如何导入和导出
查看>>