poj City Horizon (线段树+二分离散)
http://poj.org/problem?id=3277
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 15255 | Accepted: 4111 |
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 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.
Input
Output
Sample Input
4
2 5 1
9 10 4
6 8 2
4 6 3
Sample Output
16 【题解】:
这题是二分离散线段树,因为1 ≤Ai<Bi≤ 1,000,000,000,1 ≤Hi≤ 1,000,000,000显然直接建树是不可能的,因为N<40000,数据量不大可以先离散化再建树
先将输入的Ai Bi Hi 保存在结构体node中,将Ai,Bi保存到一个index数组里面,排序,去重,这样每个Ai,Bi对应一个index数组的位置;
结构体node按照高度Hi排序,排序之后就不用考虑覆不覆盖的问题了,统一覆盖就行了;
【注】:被坑了,还是自己不够严谨的问题,居然数据类型以为只要用来求和的sum是__int64就可以了,可是在进行乘法的时候height*(r-l)溢出了,果断height__int64过了
坑惨了,有图有真相:

【code】:
/**
status:Accepted memory:7424K
time:407MS language:C++
code length:2904B author:cj
oj: poj submittime:2013-08-06 12:36:08
*/ #include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h> using namespace std; #define N 40010
#define lson p<<1
#define rson p<<1|1 struct Nod
{
int from,to,height;
}node[N]; struct TNod
{
int l,r;
__int64 height; //我以为只要sum值设为__int64就行了,height值也应该是__int64的,因为后面要进行乘法运算
__int64 sum;
}tnode[N<<]; bool cmp(Nod a,Nod b) //按高度排序
{
return a.height<b.height;
} int temp[N<<],index[N<<],brush[N<<]; int findPos(int a,int k) //二分查找离散
{
int l,r,mid=-;
l=;
r=k;
while(l<=r)
{
mid = (l+r)>>;
if(a<index[mid]) r=mid-;
else if(a>index[mid]) l=mid+;
else return mid;
}
return mid;
} void building(int l,int r,int p) //建树
{
tnode[p].l = l;
tnode[p].r = r;
tnode[p].height = ;
tnode[p].sum = ;
if(l+==r) return;
int mid = (l+r)>>;
building(l,mid,lson);
building(mid,r,rson);
} void update(int l,int r,int p,int h)
{
if(tnode[p].l==l&&r==tnode[p].r)
{
tnode[p].height = h;
tnode[p].sum = (index[r]-index[l])*tnode[p].height; //这里的height是64位int,相乘得64为int
return;
}
if(tnode[p].height>) //向下更新
{
tnode[lson].sum = (index[tnode[lson].r] - index[tnode[lson].l])*tnode[p].height;
tnode[rson].sum = (index[tnode[rson].r] - index[tnode[rson].l])*tnode[p].height;
tnode[lson].height = tnode[rson].height = tnode[p].height;
tnode[p].height = ;
}
int mid = (tnode[p].l+tnode[p].r)>>;
if(r<=mid) update(l,r,lson,h);
else if(l>=mid) update(l,r,rson,h);
else
{
update(l,mid,lson,h);
update(mid,r,rson,h);
}
if(tnode[lson].height&&tnode[rson].height&&tnode[lson].height==tnode[rson].height) //向上更新
{
tnode[p].height = tnode[lson].height;
}
tnode[p].sum = tnode[lson].sum + tnode[rson].sum; //向上更新
} int main()
{
int n;
scanf("%d",&n);
int i,cnt=;
for(i=;i<n;i++)
{
scanf("%d%d%d",&node[i].from,&node[i].to,&node[i].height);
temp[cnt++]=node[i].from;
temp[cnt++]=node[i].to;
}
sort(temp,temp+cnt); //排序
int j=;
index[]=temp[];
for(i=;i<cnt;i++) //去掉重复值
{
if(index[j]!=temp[i])
{
index[++j]=temp[i];
}
}
int k = j;
building(,k,);
sort(node,node+n,cmp); //按照高度排序
for(i=;i<n;i++)
{
int from = findPos(node[i].from,k);
int to = findPos(node[i].to,k);
update(from,to,,node[i].height);
}
printf("%I64d\n",tnode[].sum); //直接输出,头结点的sum值
return ;
}
poj City Horizon (线段树+二分离散)的更多相关文章
- poj 3277 City Horizon (线段树 扫描线 矩形面积并)
题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...
- hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)
http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others) ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- hdu4614 线段树+二分 插花
Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
- luogu4422 [COCI2017-2018#1] Deda[线段树二分]
讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...
- Buy Tickets POJ - 2828 思维+线段树
Buy Tickets POJ - 2828 思维+线段树 题意 是说有n个人买票,但是呢这n个人都会去插队,问最后的队列是什么情况.插队的输入是两个数,第一个是前面有多少人,第二个是这个人的编号,最 ...
随机推荐
- java性能
一.关于性能的基本知识 1.性能的定义 在我们讨论怎样提高Java的性能之前,我们需要明白“性能“的真正含义.我们一般定义如下五个方面作为评判性能的标准. 1) 运算的性能----哪一个算法的执 ...
- CSS3 变形记
CSS3 变形 CSS3变形是一些效果的集合,比如平移,旋转,缩放和倾斜效果,每个效果都称为变形函数. transform transform属性向元素应用 2D 或 3D 转换.该属性允许我们对元素 ...
- Linux 命令 - printenv: 打印全部或部分环境信息
命令格式 printenv [OPTION]... [VARIABLE]... 命令参数 -0, --null 以空字符而非换行符结束每一输出行. --help 显示帮助信息. --version 显 ...
- JAVA开发:分享一些SpringMvc+Ibatis+spring的框架使用心得
近期不在做.net的项目,而是使用java作为开发语言,就想着要用springmvc开发了,由于前些年也用过struts1/2+hibernate/ibatis+spring开发过项目,因此是有些底子 ...
- 使用TreeView+ListBox+TxtBox 资料管理器
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- JSP连接mysql 驱动包
360网盘 https://yunpan.cn/cPxT6CV9Kydyb 访问密码 1df9
- Visual Studio的MethMVVM
MethMVVM介绍: Visual Studio Gallery是微软针对VisualStudio扩展提供的一种解决方案,在Visual Studio Gallery你能够找到各种不同主题的解决方案 ...
- Android 开机自启动应用
Android启动时,会发出一个系统广播 ACTION_BOOT_COMPLETED,它的字符串常量表示为 “android.intent.action.BOOT_COMPLETED” 开机自启动程序 ...
- js知识简单归纳
js简单的归纳 基本类型 number,string,boolean,null,undefined 组合类型 一种对象类型: object 数组 函数 对象 正则 关于函数 作用域 闭包 构造函数 原 ...
- javascript笔记—— 构造函数
出处:http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html 数据类型 ...