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个人都会去插队,问最后的队列是什么情况.插队的输入是两个数,第一个是前面有多少人,第二个是这个人的编号,最 ...
随机推荐
- 转:一个C语言实现的类似协程库(StateThreads)
http://blog.csdn.net/win_lin/article/details/8242653 译文在后面. State Threads for Internet Applications ...
- C#基础性问题
解决方案.项目.类之间的关系: 一个解决方案可以包含多个项目.一个项目可以包含多个类 解决方案:公司 项目:部门 类:员工 .sln:解决方案文件,里面包含着整个解决方案的信息,可以双击运行. .cs ...
- 纯CSS制作“跳动的心”demo
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- java createSQLQuery().list()返回日期格式没有时分秒的解决方法
方法一 将Oracel数据库对应表中“收单时间的字段”receive_sheet_time,由原来的Date类型改为timestamp 然后,在java程序中,由 (java.util.timesta ...
- 我的手机华为荣耀7,运行android程序不输出Log
解决方法:1 进入手机拨号界面2 输入*#*#2846579#*#*3 输入完毕后自动跳转到<工程菜单>界面4 依次选择后台设置-->LOG设置-->在此可以看见一些列关于LO ...
- Oracle 简介 三层结构
引言: 主流数据库:sql server, oracle, my sql,IBM公司的DB2 ,oracle占有量很大 dbms(database management system)数据库管理系统 ...
- abstract
/// <summary> /// 抽象类不能被直接实例化 /// is a /// </summary> public abstract class BasePhone { ...
- UvaLive7362 Fare(欧拉函数)
题意:求1~n的素因子之和. 分析:欧拉函数 #include<cstdio> #include<cstring> #include<cctype> #includ ...
- 怎样把SEL放进NSArray里
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3805270.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- ZigBee 入网详解
本文将根据Sniffer来详细解释ZigBee终端设备入网的整个流程,原创博文. 当协调器建立好网络后,终端设备执行zb_startrequest函数,准备入网时,他们两者之间详细的流程如下.