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

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

题目描述

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个矩形块,交求面积并.

输入

* 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

输出

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

样例输入

4

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

样例输出

16


题解

离散化+线段树(话说silver就已经涉及到这么复杂的线段树了?)

由于点的坐标值过大,需要离散化。

然后将矩形按照高度从小到大排序。

使用线段树,依次将区间内所有高度修改为height。

最后区间查询(其实不算区间查询,因为求的就是sum[1])

然而这道题不是一般的储存点的线段树,而是储存线段的线段树。

线段之间是连着的,这与点不同,所以需要在原来的基础上做一些小修改,详见程序。

应该不怎么难理解。

#include 
#include
#define lson l , mid , x << 1#define rson mid , r , x << 1 | 1 //not "mid+1,r,x<<1|1"#define N 40001using namespace std;struct data{ long long a , b , h; int left , right;}k[N];struct pt{ long long num; int from;}p[N << 1];long long sum[N << 3] , tag[N << 3] , pos[N << 1];int tot;bool cmp1(pt a , pt b){ return a.num < b.num;}bool cmp2(data a , data b){ return a.h < b.h;}void pushup(int x){ sum[x] = sum[x << 1] + sum[x << 1 | 1];}void pushdown(int l , int r , int x){ if(tag[x]) { int mid = (l + r) >> 1; sum[x << 1] = tag[x] * (pos[mid] - pos[l]); sum[x << 1 | 1] = tag[x] * (pos[r] - pos[mid]); //not "pos[mid+1]" tag[x << 1] = tag[x << 1 | 1] = tag[x]; tag[x] = 0; }}void update(int b , int e , long long a , int l , int r , int x){ if(b <= l && r <= e) { sum[x] = a * (pos[r] - pos[l]); tag[x] = a; return; } pushdown(l , r , x); int mid = (l + r) >> 1; if(b < mid) update(b , e , a , lson); //not "b<=mid" if(e > mid) update(b , e , a , rson); pushup(x);}int main(){ int n , i , rnd = 0; scanf("%d" , &n); for(i = 0 ; i < n ; i ++ ) { scanf("%lld%lld%lld" , &k[i].a , &k[i].b , &k[i].h); p[tot].num = k[i].a; p[tot ++ ].from = i; p[tot].num = k[i].b; p[tot ++ ].from = i; } sort(p , p + tot , cmp1); for(i = 0 ; i < tot ; i ++ ) { if(i == 0 || p[i].num != p[i - 1].num) rnd ++ ; if(k[p[i].from].a == p[i].num) k[p[i].from].left = rnd; if(k[p[i].from].b == p[i].num) k[p[i].from].right = rnd; pos[rnd] = p[i].num; } sort(k , k + n , cmp2); for(i = 0 ; i < n ; i ++ ) update(k[i].left , k[i].right , k[i].h , 1 , rnd , 1); printf("%lld\n" , sum[1]); return 0;}

转载于:https://www.cnblogs.com/GXZlegend/p/6281762.html

你可能感兴趣的文章
NSSet和NSArray区别与方法总结
查看>>
Python列表 元组 字典 集合
查看>>
foreach遍历数组、数组的转置与方阵的迹
查看>>
Still unable to dial persistent://blog.csdn.net:80 after 3 attempts
查看>>
HTML超文本标记语言(九)——表单输入类型
查看>>
基于busybox制作mini2440根文件系统及使用nfs挂载
查看>>
信道容量及信道编码原理学习
查看>>
关于信息论中熵、相对熵、条件熵、互信息、典型集的一些思考
查看>>
浅谈独立特征(independent features)、潜在特征(underlying features)提取、以及它们在网络安全中的应用...
查看>>
从随机过程的熵率和马尔科夫稳态过程引出的一些思考 - 人生逃不过一场马尔科夫稳态...
查看>>
《A First Course in Abstract Algebra with Applications》-chaper1-数论-关于素数
查看>>
ORA-3136
查看>>
算法笔记_145:拓扑排序的应用(Java)
查看>>
JS获取农历日期
查看>>
PHP中的HTTP协议
查看>>
CSS给文字描边实现发光文字
查看>>
Java WebService入门实例
查看>>
css样式之补充
查看>>
结构与联合
查看>>
关于JS历史
查看>>