题目链接

题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积。

分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不会出错,

所有的区间都能列出来,只是在查找的时候费点事。

给的矩形相当于在同一水平线上的,也就是y1坐标相当于为0,其他的就和 poj 1151 Atlantis 差不多了。

我写的思路是按照矩形面积并的思路写的:

但是还有另一种方法也是挺简单的,就是把给的矩形按照高从小到大排序,然后依次插入线段树,后面插入的

高会覆盖前面矮的,也就是覆盖了矩形的高,查找的时候按照00 11 22这种区间查找,只有找到h!=0的就是

当前的高,因为这表示这是后来插入的,也就是高的,然后乘上x的范围就是面积了。

 #include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
#define lson l, mid, 2*rt
#define rson mid+1, r, 2*rt+1
const int maxn = +;
using namespace std;
int n;
double y[maxn];
struct node
{
int l, r, c;
int cnt, lf, rf;
}tr[*maxn];
struct Line
{
int x, y1, y2;
int f;
}line[maxn];
bool cmp(Line a, Line b)
{
return a.x < b.x;
}
void build(int l, int r, int rt)
{
tr[rt].l = l; tr[rt].r = r;
tr[rt].cnt = tr[rt].c = ;
tr[rt].lf = y[l]; tr[rt].rf = y[r];
if(l+==r) return;
int mid = (l+r)/;
build(l, mid, *rt);
build(mid, r, *rt+);
}
void calen(int rt)
{
if(tr[rt].c>)
{
tr[rt].cnt = tr[rt].rf-tr[rt].lf;
return;
}
if(tr[rt].l+==tr[rt].r) tr[rt].cnt = ;
else tr[rt].cnt = tr[*rt].cnt+tr[*rt+].cnt;
}
void update(int rt, Line e)
{
if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
{
tr[rt].c += e.f;
calen(rt);
return;
}
if(e.y2<=tr[*rt].rf) update(*rt, e);
else if(e.y1>=tr[*rt+].lf) update(*rt+, e);
else
{
Line tmp = e;
tmp.y2 = tr[*rt].rf;
update(*rt, tmp);
tmp = e;
tmp.y1 = tr[*rt+].lf;
update(*rt+, tmp);
}
calen(rt);
}
int main()
{
int i, cnt;
LL ans;
int a, b, h;
while(~scanf("%d", &n))
{
cnt = ; ans = ;
for(i = ; i < n; i++)
{
scanf("%d%d%d", &a, &b, &h);
line[cnt].x = a; line[cnt].y1 = ;
line[cnt].y2 = h; line[cnt].f = ;
y[cnt++] = ;
line[cnt].x = b; line[cnt].y1 = ;
line[cnt].y2 = h; line[cnt].f = -;
y[cnt++] = h; }
sort(line+, line+cnt, cmp);
sort(y+, y+cnt);
int m = unique(y+, y+cnt)-(y+); //对y坐标去重,不去重也没错
build(, m, ); update(, line[]);
for(i = ; i < cnt; i++)
{
ans += (LL)tr[].cnt*(line[i].x-line[i-].x);
update(, line[i]);
}
printf("%I64d\n", ans);
}
return ;
}

poj 3277 City Horizon (线段树 扫描线 矩形面积并)的更多相关文章

  1. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  2. 离散化+线段树 POJ 3277 City Horizon

    POJ 3277 City Horizon Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18466 Accepted: 507 ...

  3. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  4. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  5. poj City Horizon (线段树+二分离散)

    http://poj.org/problem?id=3277 City Horizon Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

  6. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  7. POJ 1151 Atlantis 线段树求矩形面积并 方法详解

    第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...

  8. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  9. 【hdu1542】线段树求矩形面积并

    分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...

随机推荐

  1. c语言基础:各种数据类型的输出占位符

    c语言中的输出操作相对java来说是比较麻烦的,每种数据类型的输出都有各自的占位符: 下面是各种数据类型的输出占位符: short/int : %d ; printf("这个整数是:%d&q ...

  2. python 链接hive

    http://blog.csdn.net/xubcing/article/details/8350287 http://www.centoscn.com/python/2014/0921/3801.h ...

  3. [原]android不支持命名的semaphore

    之前sem_open在iOS上, 创建命名的semaphore没有问题 (iOS不支持匿名的semaphore), 但是现在Android平台的sem_open时候报错,返回ENOSYS. 命名的se ...

  4. BT5之Metasploit[MSF]连接postgresql数据库

    1,先查看postgresql的端口,默认是自动开启的,端口7337 .   root@bt:~# netstat -tnpl |grep postgres tcp        0      0 1 ...

  5. dom4j处理xml文件,读取xml字符串,格式化xml文件

    1.xml文件 <?xml version="1.0" encoding="UTF-8"?> <employees> <emplo ...

  6. How to use Mac Terminal

    Mac OS X 启用超级用户的方法Root user,又名超级用户,是一个权力最高的Unix 账户,Root 的账户能在整个系统里任何部份进行任何“操作”,包括:拷贝档案.移动/移除档案.执行程序等 ...

  7. POJ2632Crashing Robots

    做模拟题做的我直接睡着了,题并不难,就是一个细心的问题,有一些细节问题注意了就差不多了,代码写的精美的一般找错误也好找一些,应该学着些好看的代码 #include<cstdio> #inc ...

  8. sql查询数据库中所有表的记录条数,以及占用磁盘空间大小。

    SELECT TableName = obj.name, TotalRows = prt.rows, [SpaceUsed(KB)] = SUM(alloc.used_pages)* FROM sys ...

  9. Java 编译错误:缺少返回语句

    示例: import java.util.*; import java.io.*; public class tt { public static void main(String[] args) { ...

  10. SaaS系列介绍之十二: SaaS产品的研发模式

    1 产品研发模式慨述 产品研发模式是企业战略的重点.产品研发路线决定了一系列的管理手段和团队建设问题.也是企业的整理策略和经营思路.产品研发模式贯穿着整个产品的生命周期,从市场调研.立项.需求分析.慨 ...