【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
【题目】
Atlantis
Problem DescriptionThere are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.InputThe input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don’t process it.OutputFor each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.Sample Input2
10 10 20 20
15 15 25 25.5
0Sample OutputTest case #1
Total explored area: 180.00
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解。所以自己打算写一个详细的。看完必会o(∩_∩)o
顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中,这根线很重要。方向的话,可以左右扫,也可以上下扫。方法是一样的,这里我用的是由下向上的扫描法。
如上图所示,坐标系内有两个矩形。位置分别由左下角和右上角顶点的坐标来给出。上下扫描法是对x轴建立线段树,矩形与y平行的两条边是没有用的,在这里直接去掉。如下图。
现想象有一条线从最下面的边开始依次向上扫描。线段树用来维护当前覆盖在x轴上的线段的总长度,初始时总长度为0。用ret来保存矩形面积总和,初始时为0。
由下往上扫描,扫描到矩形的底边时将它插入线段树,扫描到矩形的顶边时将底边从线段树中删除。而在代码中实现的方法就是,每条边都有一个flag变量,底边为1,顶边为-1。
用cover数组(通过线段树维护)来表示某x轴坐标区间内是否有边覆盖,初始时全部为0。插入或删除操作直接让cover[] += flag。当cover[] > 0 时,该区间一定有边覆盖。
开始扫描到第一条线,将它压入线段树,此时覆盖在x轴上的线段的总长度L为10。计算一下它与下一条将被扫描到的边的距离S(即两条线段的纵坐标之差,该例子里此时为3)。
则 ret += L * S. (例子里增量为10*3=30)
结果如下图
橙色区域表示已经计算出的面积。
扫描到第二条边,将它压入线段树,计算出此时覆盖在x轴上的边的总长度。
例子里此时L=15。与下一条将被扫描到的边的距离S=2。 ret += 30。 如下图所示。
绿色区域为第二次面积的增量。
接下来扫描到了下方矩形的顶边,从线段树中删除该矩形的底边,并计算接下来面积的增量。如下图。
蓝色区域为面积的增量。
此时矩形覆盖的总面积已经计算完成。 可以看到,当共有n条底边和顶边时,只需要从下往上扫描n-1条边即可计算出总面积。
此题因为横坐标包含浮点数,因此先离散化。另外,因为用线段树维护的是覆盖在x轴上的边,而边是连续的,并非是一个个断点,因此线段树的每一个叶子结点实际存储的是该点与下一点之间的距离。
12.25
自己总结:
这道题我一直在纠结,怎么求当前有扫描线上有的线段总长?怎么lazy下放?我一直想的是每个点维护的都是它维护的这个区间内的总的cnt等等。
后来我发现换个思路,一切都很简单!
我的每个节点t[x].l~t[x].r维护的其实是线段t[x].l~(t[x].r+1),也就是若干条线段,因为点分成左右孩子的时候会有问题(比如[3,3]维护的到底是什么?)。
我们要把每个节点看成是一条线段。
对于每个节点维护两个值:
cnt:这个点所代表的线段被覆盖了多少次。
len:以这个点为根的子树中被覆盖的区间一共有多长。
当一条线段进来的时候,在代表它的那若干个节点上cnt++,其它节点cnt不用加。
然后len维护的就是这个区间内那些cnt>0的节点所覆盖的区间总长。
我做惯了叶子节点才有实际意义的线段树,思路太过狭隘,被卡了这么久,其实线段树上每个节点都可以有它的实际意义。
【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)的更多相关文章
- (HDU 1542) Atlantis 矩形面积并——扫描线
n个矩形,可以重叠,求面积并. n<=100: 暴力模拟扫描线.模拟赛大水题.(n^2) 甚至网上一种“分块”:分成n^2块,每一块看是否属于一个矩形. 甚至这个题就可以这么做. n<=1 ...
- poj-1151矩形面积并-线段树
title: poj-1151矩形面积并-线段树 date: 2018-10-30 22:35:11 tags: acm 刷题 categoties: ACM-线段树 概述 线段树问题里的另一个问题, ...
- hdu 1255 覆盖的面积(线段树 面积 交) (待整理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. In ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...
- POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- POJ 1151Atlantis 矩形面积并[线段树 离散化 扫描线]
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21734 Accepted: 8179 Descrip ...
- HDU 1255 覆盖的面积 ——(线段树+扫描线)
又做了一题扫描线以后对节点的覆盖标记理解的更加深刻了. 代码如下: #include <stdio.h> #include <algorithm> #include <s ...
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)
自己YY了一个的写法,不过时间复杂度太高了,网上的想法太6了 题意:给你一些矩阵,求出矩阵的面积并 首先按照x轴离散化线段到线段树上(因为是找连续区间,所以段建树更加好做). 然后我们可以想一下怎样 ...
- HDU - 1255 覆盖的面积 (线段树求面积交)
https://cn.vjudge.net/problem/HDU-1255 题意 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 分析 求面积并的题:https://www.cnbl ...
随机推荐
- 怎么在AptanaStudio中把电脑中的浏览器设置为默认执行方法
1.在Aptana中找到按钮 2.点击向下的三角形找到
- 1.shell之搭建Shell编程环境
第一次写博客,加点废话,学习linux有一段时间,随着学习的深入发现自己学的不够系统,特别是遇到一些莫名的问题时,我只有各种百度,运气好时能解决掉,差时到现在还没解决,就算解决了还是不清楚是怎么解决的 ...
- 第十篇:web之前端之django一些feature
前端之django一些feature 前端之django一些feature 本节内容 cookie session 跨站请求保护 分页 序列化 model模块 CBV和FBV 模板渲染对象 1. ...
- JavaScript入门(5)
一.什么是数组? 数组是一个值的集合,每一个值都有一个索引号,从0开始,每个索引都有一个相应的值,根据需要添加更多数值. 好比一个团,团里有很多人.如下使用数组存储5个学生成绩: 二.如何创建数组 使 ...
- html5 video.js 使用及兼容所有浏览器
废话少说,直接开始 一.准备材料 video.js下载: http://www.videojs.com/ 二.代码 引入相关文件:(必须放在文件的开头,也是说一定要放在video标签之前) 贴入htm ...
- CSS3 transition-timing-function
CSS3 transition-timing-function 属性 定义和用法 transition-timing-function 属性规定过渡效果的速度曲线. 该属性允许过渡效果随着时间来改变其 ...
- facebook登录(集成FBSDKLoginKit) result的isCancelled总是YES token为nil
只需要在AppDelegate如下函数添加: - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDict ...
- libCURL动态分配buffer——节约内存
libCURL是一个免费的.开源的强大客户端url传输库.支持的平台.协议甚广.平台上有Windows.Linux.FreeBSD:协议上有FTP.HTTP(S).Telnet.DICT.File等. ...
- 工具系列之Sublime Text 3 使用总结
1.Sublime Text 2/3如何支持中文GBK编码(解决中文乱码) Sublime Text默认是只支持UTF8的编码,所以有些时候,当我们打开GBK文件时候,文件内会出先部分的乱码,如下图 ...
- Codevs 2597 团伙(并查集)
2597 团伙 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么 ...


橙色区域表示已经计算出的面积。
绿色区域为第二次面积的增量。
蓝色区域为面积的增量。