title: poj-1151矩形面积并-线段树

date: 2018-10-30 22:35:11

tags:

  • acm
  • 刷题

    categoties:
  • ACM-线段树

概述

线段树问题里的另一个问题,,,矩形面积并,,,,

之前看lazy更新时看到下面这个的讲解,,,一大堆文字还有一大堆的图,,,,当时果断跳过,,,

今天花了一下午加一晚上的时间看了看这块知识,,,然后尝试自己写出代码,,,算是简单的了解一下这块,,,

题意

这道矩形面积并问题的大意是给很多个矩形,,矩形之间可能有交集,,,然后问你这一大片的图形面积是多少,,,,

数据量不大,,看到有很多人是暴力过的,,,

但是用线段树来当作练习题锻炼锻炼思维还是很好的QAQ

思路

一开始我是看这篇博客有关矩形面积并的知识,,,

这篇博客讲解的思路很不错,,,一遍之后大致了解了整个解决问题的思路,,,,但是它没有相应的练习题以及代码,,,,我完全不知道该从哪里下手,,,线段树的具体如何实现一脸懵逼,,,,还有,,,一般这种题都是要将一个方向的坐标 离散化,,,,嗯,,又是这个东西,,,,更是一脸的懵逼,,,,

然后看了这篇博客,,对着代码,,,然后顺着思路写出来了,,,

主要的几点:

  • 前面两个博客的图很形象的把思路理了一遍,,,,就是枚举一个方向,,比如y方向,,然后,,将x方向的坐标离散化,,分成若干个 单位线段,,,,线段树维护这个单位线段,,,还是那个博客形象一些
  • 整个图形的面积可以分成若干个小的矩形,,,然后加起来就行,,,,

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm> using namespace std;
#define aaa cout << x[r + 1] << "----" << x[l] << endl;
const int maxn = 205;
double x[maxn << 2]; //所有的x的数据
//每一条线段
struct segment
{
double y;
double l;
double r;
int flag; //1 or -1: 入边or出边
segment(){}
segment(double y, double l , double r , int flag):y(y) , l(l) , r(r) , flag(flag){}
bool operator < (const segment &res)
{
return y < res.y;
}
}seg[maxn << 1]; //线段树维护所有的单位线段(离散后的)
struct node
{
int cov;
double len;
}node[maxn << 2];
void pushdown(int rt , int l , int r)
{
if(node[rt].cov)
node[rt].len = x[r + 1] - x[l];
else if(l == r)
node[rt].len = 0;
else
node[rt].len = node[rt << 1].len + node[rt << 1 | 1].len;
}
void update(int rt , int l , int r , int L , int R , int cov)
{
if(L <= l && r <= R)
{
node[rt].cov += cov;
pushdown(rt , l , r);
return;
}
int mid = (l + r) >> 1;
if(L <= mid) update(rt << 1 , l , mid , L , R , cov);
if(R > mid) update(rt << 1 | 1 , mid + 1 , r , L , R , cov);
//pushdown
pushdown(rt , l , r);
return;
} int main()
{
int n;
int q = 1;
while(scanf("%d" , &n) && n)
{
memset(x , 0 , sizeof x); double x1 , y1 , x2 , y2;
int count = 0;
for(int i = 0; i < n; ++i)
{
scanf("%lf%lf%lf%lf" , &x1 , &y1 , &x2 , &y2);
seg[count]=segment(y1 , x1 , x2 , 1);
x[count++] = x1;
seg[count]=segment(y2 , x1 , x2 , -1);
//segment[i].y = y1;segment[i].l = x1;segment[i].r = x2;segment[i].flag = 1;
//segment[i + 1].y = y2;segment[i + n].l = x1;segment[i + n].r = x2;segment[i + n].flag = -1; x[count++] = x2;
}
//离散
sort(seg , seg + count);
sort(x , x + count); int sz = unique(x , x + count) - x;
double ans = 0;
for(int i = 0; i < count; ++i)
{
int l = lower_bound(x , x + sz , seg[i].l) - x;
int r = lower_bound(x , x + sz , seg[i].r) - x - 1;
update(1 , 0 , sz , l , r , seg[i].flag);
ans += node[1].len * (seg[i + 1].y - seg[i].y);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",q++,ans);
}
}

总结

算了,,,先鸽了,,,细节那天再补一下,,,,

(loading,,,,)

poj-1151矩形面积并-线段树的更多相关文章

  1. POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21734   Accepted: 8179 Descrip ...

  2. POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并

    题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...

  3. POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21734   Accepted: 8179 Descrip ...

  4. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  5. hdu 1255 覆盖的面积(线段树 面积 交) (待整理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.   In ...

  6. POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)

    POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...

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

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

  8. HDU 3265/POJ 3832 Posters(扫描线+线段树)(2009 Asia Ningbo Regional)

    Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the ...

  9. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

随机推荐

  1. plsql developer导入数据库

    需要指向导入命令

  2. 2017萧山第5场(2016 Pacific Northwest - Division 1)

    B:Buggy Robot [题意] 一个n*m的地图(1≤n, m≤50),有一个入口和一个出口.给定一个命令序列(上,下,左,右),如果碰到障碍或者边际就忽略.问至少加入或删除多少个的命令,使得能 ...

  3. 七牛云 上传图片 https 修改Nginx 注意事项

    仅在这记录下,今天的事情. 问题出自于Nginx 设置http 强制跳转 https设置 1.上午,出于某些需求,我将服务器Nginx 设置http 强行跳转 https server { liste ...

  4. HaoZipC不是内部或外部命令

    Win7专业版,32位,HaoZip V3.2 将安装命令下HaoZipC.exe,HaoZip.dll,lang\HaoZipLang_chs.dll三个文件拷贝到C:\Windows\System ...

  5. aarch64_p1

    PEGTL-devel-1.3.1-2.fc26.aarch64.rpm 2017-02-14 08:00 63K fedora Mirroring Project PackageKit-1.1.6- ...

  6. java 判断上传文件大小

    /** * 判断文件大小 * * @param file * 文件 * @param size * 限制大小 * @param unit * 限制单位(B,K,M,G) * @return */ pu ...

  7. C# 调用WSDL接口及方法

    1.首先需要清楚WSDL的引用地址 如:http://XX.XX.4.146:8089/axis/services/getfileno?wsdl 上述地址的构造为 类名getfileno. 2.在.N ...

  8. 数据库——mysql如何获取当前时间

    1.1 获得当前日期+时间(date + time)函数:now() 除了 now() 函数能获得当前的日期时间外,MySQL 中还有下面的函数: current_timestamp() curren ...

  9. 【前端vue开发】vue开发watch检测的使用

    <span style="color:#006600;"><div id="app"> <input type="tex ...

  10. python网络编程-socket上传下载文件(包括md5验证,大数据发送,粘包处理)

    ftp server 1) 读取文件名 2)检查文件是否存在 3)打开文件 4)检查文件大小 5)发送文件大小给客户端 6)等客户端确认 7)开始边读边(md5计算)发数据 8)给客户端发md5 ft ...