http://www.lydsy.com/JudgeOnline/problem.php?id=1645

这题的方法很奇妙啊。。。一开始我打了一个“离散”后的线段树。。。。。。。。。。。。。果然爆了。。(因为压根没离散)

这题我们可以画图知道,每2个点都有一个区间,而这个区间的高度是一样的,因此,我们只需要找相邻的两个点,用他们的距离×这个区间的高度就是这块矩形的面积。

将所有这样的矩形累计起来就是答案了。

因此线段树就离散到了O(n)的大小。。真神。。

只需要维护点的位置,然后维护区间最值即可(因为这是线段长度而不是两点长度,即r-l+1,所以要用一定的技巧,将这些坐标都往左边缩1,原因很简单,画图得知)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%lld", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }
typedef long long ll;
#define lc x<<1
#define rc x<<1|1
#define lson l, m, lc
#define rson m+1, r, rc
#define MID (l+r)>>1
const int N=40005;
int n, b[N+N];
ll ans;
struct dat { int x, y, h; }a[N];
struct nod { int h, flg; }t[N<<4];
void pushup(int x) { t[x].h=max(t[lc].h, t[rc].h); }
void pushdown(int x) {
if(t[x].flg) {
int flg=t[x].flg;
t[x].flg=0;
t[lc].flg=max(t[lc].flg, flg); t[lc].h=max(t[lc].h, flg);
t[rc].flg=max(t[rc].flg, flg); t[rc].h=max(t[rc].h, flg);
}
}
void update(int l, int r, int x, int L, int R, int fix) {
pushdown(x);
if(L<=l && r<=R) {
t[x].flg=fix;
t[x].h=max(t[x].h, fix);
return;
}
int m=MID;
if(L<=m) update(lson, L, R, fix); if(m<R) update(rson, L, R, fix);
pushup(x);
}
int query(int l, int r, int x, int L) {
pushdown(x);
if(l==r) return t[x].h;
int m=MID;
if(L<=m) return query(lson, L);
else return query(rson, L);
}
int main() {
read(n);
for1(i, 1, n) read(a[i].x), read(a[i].y), read(a[i].h), b[i<<1]=a[i].x, b[(i<<1)-1]=a[i].y;
int sz=n<<1;
sort(b+1, b+1+sz);
for1(i, 1, n) a[i].x=lower_bound(b+1, b+1+sz, a[i].x)-b, a[i].y=lower_bound(b+1, b+1+sz, a[i].y)-b;
for1(i, 1, n)
update(1, sz, 1, a[i].x, a[i].y-1, a[i].h);
for1(i, 1, sz-1)
ans+=(ll)query(1, sz, 1, i)*(ll)(b[i+1]-b[i]);
print(ans);
return 0;
}

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.

HINT

Source

【BZOJ】1645: [Usaco2007 Open]City Horizon 城市地平线(线段树+特殊的技巧)的更多相关文章

  1. BZOJ 1645: [Usaco2007 Open]City Horizon 城市地平线 扫描线 + 线段树 + 离散化

    Code: #include<cstdio> #include<algorithm> #include<string> #define maxn 1030000 # ...

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

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

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

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

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

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

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

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

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

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

  7. 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 ...

  8. 【BZOJ】1628 && 1683: [Usaco2007 Demo]City skyline 城市地平线(单调栈)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1628 http://www.lydsy.com/JudgeOnline/problem.php?id ...

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

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

随机推荐

  1. Ajv JSON数据格式校验 使用

    1.官网 https://ajv.js.org/ 2.示例代码 <!DOCTYPE html> <html lang="zh"> <head> ...

  2. 浅析CentOS和RedHat Linux的区别(转)

    CentOS的简介 CentOS是Community ENTerprise Operating System的简称,我们有很多人叫它社区企业操作系统,不管你怎么叫它,它都是Linux操作系统的一个发行 ...

  3. Oracle常用函数脑图

    全面的可参考(四)Oracle学习笔记—— 常见函数

  4. Python 调试:step into/step out/step over 的区别

    Python 调试:step into/step out/step over 的区别: 首先在PyCharm 程序中设置 “ 断点 ”,后点击右上角的Debug 按钮进入调试程序状态: step in ...

  5. 转mosquitto auth plugin 编译配置

    配置使用 mysql 作为 be (back end) 使用config.mk 配置编译参数 cp config.mk.in config.mk 修改 安装 mysql sudo apt-get in ...

  6. 51单片机晶振11.0592M延时函数

    /********************************************** º¯ÊýÃû£ºdelay_ms(uint z) ÑÓʱº¯Êý(12MHZ¾§Õñ) ´Ëº¯ÊýÑ ...

  7. IntelliJ IDEA 学习(二):Intellij IDEA 创建Web项目并在Tomcat中部署运行IDEA

    一.创建Web项目  1.File -> New Module,进入创建项目窗口 2.选择Java类型,在 Module name 处输入项目名,点击Next 3.勾选 Web Applicat ...

  8. mybatis 参数说明

    1 简单参数 <select id="selectUsers" resultType="User"> select id, username, pa ...

  9. c++,当const char*为0时,不能将其直接赋给string

    下面程序会崩溃: const char* t_objName = (obj!=NULL)?obj->getName(): 0; string objName=t_objName; cout< ...

  10. PCI-Express协议传输层读书笔记

    http://www.doczj.com/doc/35cb19633169a4517723a3d9-9.html