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

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

tags:

  • acm
  • 刷题

    categoties:
  • ACM-线段树

概述

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

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

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

题意

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

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

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

思路

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

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

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

主要的几点:

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

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <algorithm>
  6. using namespace std;
  7. #define aaa cout << x[r + 1] << "----" << x[l] << endl;
  8. const int maxn = 205;
  9. double x[maxn << 2]; //所有的x的数据
  10. //每一条线段
  11. struct segment
  12. {
  13. double y;
  14. double l;
  15. double r;
  16. int flag; //1 or -1: 入边or出边
  17. segment(){}
  18. segment(double y, double l , double r , int flag):y(y) , l(l) , r(r) , flag(flag){}
  19. bool operator < (const segment &res)
  20. {
  21. return y < res.y;
  22. }
  23. }seg[maxn << 1];
  24. //线段树维护所有的单位线段(离散后的)
  25. struct node
  26. {
  27. int cov;
  28. double len;
  29. }node[maxn << 2];
  30. void pushdown(int rt , int l , int r)
  31. {
  32. if(node[rt].cov)
  33. node[rt].len = x[r + 1] - x[l];
  34. else if(l == r)
  35. node[rt].len = 0;
  36. else
  37. node[rt].len = node[rt << 1].len + node[rt << 1 | 1].len;
  38. }
  39. void update(int rt , int l , int r , int L , int R , int cov)
  40. {
  41. if(L <= l && r <= R)
  42. {
  43. node[rt].cov += cov;
  44. pushdown(rt , l , r);
  45. return;
  46. }
  47. int mid = (l + r) >> 1;
  48. if(L <= mid) update(rt << 1 , l , mid , L , R , cov);
  49. if(R > mid) update(rt << 1 | 1 , mid + 1 , r , L , R , cov);
  50. //pushdown
  51. pushdown(rt , l , r);
  52. return;
  53. }
  54. int main()
  55. {
  56. int n;
  57. int q = 1;
  58. while(scanf("%d" , &n) && n)
  59. {
  60. memset(x , 0 , sizeof x);
  61. double x1 , y1 , x2 , y2;
  62. int count = 0;
  63. for(int i = 0; i < n; ++i)
  64. {
  65. scanf("%lf%lf%lf%lf" , &x1 , &y1 , &x2 , &y2);
  66. seg[count]=segment(y1 , x1 , x2 , 1);
  67. x[count++] = x1;
  68. seg[count]=segment(y2 , x1 , x2 , -1);
  69. //segment[i].y = y1;segment[i].l = x1;segment[i].r = x2;segment[i].flag = 1;
  70. //segment[i + 1].y = y2;segment[i + n].l = x1;segment[i + n].r = x2;segment[i + n].flag = -1;
  71. x[count++] = x2;
  72. }
  73. //离散
  74. sort(seg , seg + count);
  75. sort(x , x + count);
  76. int sz = unique(x , x + count) - x;
  77. double ans = 0;
  78. for(int i = 0; i < count; ++i)
  79. {
  80. int l = lower_bound(x , x + sz , seg[i].l) - x;
  81. int r = lower_bound(x , x + sz , seg[i].r) - x - 1;
  82. update(1 , 0 , sz , l , r , seg[i].flag);
  83. ans += node[1].len * (seg[i + 1].y - seg[i].y);
  84. }
  85. printf("Test case #%d\nTotal explored area: %.2f\n\n",q++,ans);
  86. }
  87. }

总结

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

(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. springmvc转springboot过程中访问jsp报Whitelabel Error Page错误

    前言: 虽然springboot内嵌了一个tomcat,但是这个内嵌的tomcat不支持jsp页面,所以需要引入其他包 解决: maven引入以下包即可 <dependency> < ...

  2. soj2013.Pay Back

    2013. Pay Back Constraints Time Limit: 1 secs, Memory Limit: 256 MB Description "Never a borrow ...

  3. Docker 初相见

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Li ...

  4. JS中数组那些事~

    今天闲的没事,看了一些关于数组的操作,好久木有用过,很多都已经忘记的差不多了,所以今天花了一个小时写了一些demo,准备备份一下方便以后使用~~~ 下面是一些工作当中,经常用到的数组的方法,小伙伴可以 ...

  5. 我应该记录一下我不太了解的一些c语言函数

    当然,现在还不分类 fmemopen getpagesize()

  6. 重写Java Object对象的hashCode和equals方法实现集合元素按内容判重

    Java API提供的集合框架中Set接口下的集合对象默认是不能存储重复对象的,这里的重复判定是按照对象实例句柄的地址来判定的,地址相同则判定为重复,地址不同不管内容如何都判定为不重复,这有时与需求不 ...

  7. ASP.NET 实现Base64文件流下载PDF

    因为业务需要调用接口获取的是 Base64文件流 需要提供给客户下载PDF文档 源码部分借鉴网上,具体地址忘记了. //Base64文件流 byte[] buffer = Convert.FromBa ...

  8. linux文件管理 -> vim编辑总结

    vi和vim命令是linux中强大的文本编辑器, 由于Linux系统一切皆文件,而配置一个服务就是在修改其配置文件的参数.vim编辑器是运维工程师必须掌握的一个工具, 没有它很多工作都无法完成.vim ...

  9. No.15 selenium for python JavaScript

    JS处理滚动条 一.上下滚动 1.滚动条回到顶部: js="var q=document.documentElement.scrollTop=10000" driver.execu ...

  10. Filter过滤器-JavaWeb三大组件之一

    Servlet.Filter.Listener是JavaWeb的三大组件,给Web开发提供了很大的便利. 什么是Filter? Filter,过滤器.类似与生活中的净水器.空气净化器. JavaWeb ...