很久没做线段树了

讲的比较清楚的链接

求矩形面积的并
分析:
1.矩形比较多,坐标也很大,所以横坐标需要离散化(纵坐标不需要),熟悉离散化后这个步骤不难,所以这里不详细讲解了,不明白的还请百度
2.重点:扫描线法:假想有一条扫描线,从左往右(从右往左),或者从下往上(从上往下)扫描过整个多边形(或者说畸形。。多个矩形叠加后的那个图形)。如果是竖直方向上扫描,则是离散化横坐标,如果是水平方向上扫描,则是离散化纵坐标。
下面的分析都是离散化横坐标的,并且从下往上扫描的。
扫描之前还需要做一个工作,就是保存好所有矩形的上下边,并且按照它们所处的高度进行排序,另外如果是上边我们给他一个值-1,下边给他一个值1,我们用一个结构体来保存所有的上下边
struct segment
{
double l,r,h;   //l,r表示这条上下边的左右坐标,h是这条边所处的高度
int f;   //所赋的值,1或-1
}
接着扫描线从下往上扫描,每遇到一条上下边就停下来,将这条线段投影到总区间上(总区间就是整个多边形横跨的长度),这个投影对应的其实是个插入和删除线段操作。还记得给他们赋的值1或-1吗,下边是1,扫描到下边的话相当于往总区间插入一条线段,
上边-1,扫描到上边相当于在总区间删除一条线段(如果说插入删除比较抽象,
那么就直白说,扫描到下边,投影到总区间,对应的那一段的值都要增1,扫描到上边对应的那一段的值都要减1,如果总区间某一段的值为0,说明其实没有线段覆盖到它,为正数则有,那会不会为负数呢?是不可能的,可以自己思考一下)。
每扫描到一条上下边后并投影到总区间后,就判断总区间现在被覆盖的总长度,然后用下一条边的高度减去当前这条边的高度,乘上总区间被覆盖的长度,就能得到一块面积,并依此做下去,就能得到最后的面积

Sample Input
2
10 10 20 20
15 15 25 25.5
0

Sample Output
Test case #1
Total explored area: 180.00

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cctype>
  4. #include <algorithm>
  5. using namespace std;
  6. #define lson l , m , rt << 1
  7. #define rson m + 1 , r , rt << 1 | 1
  8.  
  9. const int maxn = ;
  10. int cnt[maxn << ];
  11. double sum[maxn << ];
  12. double X[maxn];
  13. struct Seg {
  14. double h , l , r;
  15. int s;
  16. Seg(){}
  17. Seg(double a,double b,double c,int d) : l(a) , r(b) , h(c) , s(d) {}
  18. bool operator < (const Seg &cmp) const {
  19. return h < cmp.h;
  20. }
  21. }ss[maxn];
  22. void PushUp(int rt,int l,int r) {
  23. if (cnt[rt]) sum[rt] = X[r+] - X[l];
  24. else if (l == r) sum[rt] = ;
  25. else sum[rt] = sum[rt<<] + sum[rt<<|];
  26. }
  27. void update(int L,int R,int c,int l,int r,int rt) {
  28. if (L <= l && r <= R) {
  29. cnt[rt] += c;
  30. PushUp(rt , l , r);
  31. return ;
  32. }
  33. int m = (l + r) >> ;
  34. if (L <= m) update(L , R , c , lson);
  35. if (m < R) update(L , R , c , rson);
  36. PushUp(rt , l , r);
  37. }
  38. int Bin(double key,int n,double X[]) {
  39. int l = , r = n - ;
  40. while (l <= r) {
  41. int m = (l + r) >> ;
  42. if (X[m] == key) return m;
  43. if (X[m] < key) l = m + ;
  44. else r = m - ;
  45. }
  46. return -;
  47. }
  48. int main() {
  49. int n , cas = ;
  50. while (~scanf("%d",&n) && n) {
  51. int m = ;
  52. while (n --) {
  53. double a , b , c , d;
  54. scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
  55. X[m] = a;
  56. ss[m++] = Seg(a , c , b , );
  57. X[m] = c;
  58. ss[m++] = Seg(a , c , d , -);
  59. }
  60. sort(X , X + m);
  61. sort(ss , ss + m);
  62. int k = ;
  63. for (int i = ; i < m ; i ++) {
  64. if (X[i] != X[i-]) X[k++] = X[i];
  65. }
  66. memset(cnt , , sizeof(cnt));
  67. memset(sum , , sizeof(sum));
  68. double ret = ;
  69. for (int i = ; i < m - ; i ++) {
  70. int l = Bin(ss[i].l , k , X);
  71. int r = Bin(ss[i].r , k , X) - ;
  72. if (l <= r) update(l , r , ss[i].s , , k - , );
  73. ret += sum[] * (ss[i+].h - ss[i].h);
  74. }
  75. printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++ , ret);
  76. }
  77. return ;
  78. }

hdu 1542 扫描线求矩形面积的并的更多相关文章

  1. HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)

    传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...

  2. hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  3. HDU 1542 Atlantis(矩形面积并)

    HDU 1542 Atlantis 题目链接 题意:给定一些矩形,求面积并 思路:利用扫描线,因为这题矩形个数不多,直接暴力扫就能够了.假设数据大.就要用线段树 代码: #include <cs ...

  4. HDU 3265 扫描线(矩形面积并变形)

    Posters Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  5. 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)

    [题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...

  6. 2015 UESTC 数据结构专题E题 秋实大哥与家 线段树扫描线求矩形面积交

    E - 秋实大哥与家 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 De ...

  7. hdu1828 线段树扫描线求矩形面积的周长

    题意:       给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路:       线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...

  8. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  9. HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板

    好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...

随机推荐

  1. 学习Linux下的IP地址地理位置信息显示工具nali

    首先详细教程已经有前辈做了详细的安装和使用介绍,本人只是参照学习和记录下自己的实际操做. 本文参考档:http://www.cnblogs.com/mchina/archive/2012/12/24/ ...

  2. 超常用的PHP正则表达式收集整理

    以下就是对超常用的PHP正则表达式进行的收集整理,为了方便大家更快更好的掌握php正则表达式. 一.表单验证匹配验证账号,字母开头,允许 5-16 字节,允许字母数字下划线:^[a-zA-Z][a-z ...

  3. 用纯原生js实现jquery的ready函数(两种实现)

    第一种实现方式: var dom = new function() { var dom = []; dom.isReady = false; dom.isFunction = function(obj ...

  4. 读>>>>白帽子讲Web安全<<<<摘要→我推荐的一本书→1

      <白帽子讲Web安全>吴翰清著 刚开始看这本书就被这本书吸引,感觉挺不错,给大家推荐下,最近读这本书,感觉不错的精华就记录下, 俗话说>>>好脑袋不如一个烂笔头< ...

  5. 繁华模拟赛 Evensgn的债务

    #include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...

  6. C语言课程1——Hello World

    相信大家看了第一篇文章后,都信心满满,后边咱来点实际吧,上代码,经典之作:Hello World. 首先,不知道大家用的什么工具,VC6.0(太老了,强烈建议不用),VS,或是其他~ Hello Wo ...

  7. 使用HTML5 Web存储的localStorage和sessionStorage方式

    localStorage(本地存储),可以长期存储数据,没有时间限制,一天,一年,两年甚至更长,数据都可以使用.sessionStorage(会话存储),只有在浏览器被关闭之前使用,创建另一个页面时同 ...

  8. Centos 7 安装LAMP环境

    一.安装Centos 官网下载Centos 7刻录成光盘后安装 二.安装apache yum install httpd #根据提示,输入Y安装即可成功安装 systemctl start httpd ...

  9. Linux_DHCP服务搭建

    Linux网络参数的设置 1.        修改主机名 # vim /etc/sysconfig/network NETWORKING=yes HOSTNAME=bj.com 2.        修 ...

  10. Java RMI 框架

    RMI(即Remote Method Invoke 远程方法调用).在Java中,只要一个类extends了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定 ...