经典题,线段树扫描线其实类似区间更新,一般的做法是想象一根扫描线从上扫到下或者从左扫到右,本题的做法是从上扫到下

只要扫到了一根水平线,就将其更新到线段树对应区间中,区间和它的子区间是独立更新的

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<algorithm>
  5. #define maxn 2000
  6. #define lson l,m,rt<<1
  7. #define rson m+1,r,rt<<1|1
  8. using namespace std;
  9. struct Seg{
  10. double l,r,h;
  11. int d;
  12. Seg(){}
  13. Seg(double a,double b,double c,int dd):l(a),r(b),h(c),d(dd){}
  14. bool operator<(const Seg & a)const{
  15. return h<a.h;
  16. }//从下往上扫描
  17. }segs[maxn];//横线段
  18. double data[maxn];
  19. int tot,m;//data统计高度
  20. int cnt[maxn<<];//覆盖了这一整个区间的入边数 - 覆盖了这一整个区间的出边数
  21. double sum[maxn<<];//区间当前被覆盖的长度
  22. inline void pushup(int l,int r,int rt){
  23. //前两个if对应的是update中(L<=l && R>=r)的pushup,后一个if对应的是分开更新后的update
  24. if(cnt[rt])//如果这个区间都被覆盖了
  25. sum[rt]=data[r+]-data[l];
  26. else if (l==r)//如果是单位段并且cnt[rt]==0,说明这一段就是没有被覆盖
  27. sum[rt]=;
  28. else sum[rt]=sum[rt<<]+sum[rt<<|];
  29. }
  30. //更新函数update:如果整个区间被更新,分三种情况:1.这个区间被完全覆盖 2.这个区间是空白单位区间(没有子区间) 3.这个区间没有被完全覆盖
  31. void update(int L,int R,int c,int l,int r,int rt){
  32. if(L<=l && R>=r){
  33. cnt[rt]+=c;
  34. pushup(l,r,rt);//为什么这里也会有pushup?因为pushup的功能不只是合并两个区间而已,它还能计算这个区间的覆盖长度
  35. return;
  36. }
  37. int m=l+r>>;
  38. if(L<=m) update(L,R,c,lson);
  39. if(R>m) update(L,R,c,rson);
  40. pushup(l,r,rt);
  41. }
  42. void init(){
  43. tot=m=;
  44. memset(cnt,,sizeof cnt);
  45. memset(sum,,sizeof sum);
  46. }
  47. int main(){
  48. int T=,n;
  49. while(scanf("%d",&n) && n){
  50. init();
  51.  
  52. for(int i=;i<=n;i++){
  53. double x1,y1,x2,y2;
  54. scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
  55. segs[tot]=Seg(x1,x2,y1,);data[tot++]=x1;
  56. segs[tot]=Seg(x1,x2,y2,-);data[tot++]=x2;
  57. }
  58. sort(segs,segs+tot);
  59. sort(data,data+tot);
  60. m=unique(data,data+tot)-data;
  61.  
  62. double ret=;
  63. for(int i=;i<tot;i++){
  64. int posl=lower_bound(data,data+m,segs[i].l)-data;
  65. int posr=lower_bound(data,data+m,segs[i].r)-data-;
  66. if(posl<=posr)
  67. update(posl,posr,segs[i].d,,m,);//把这条边更新到线段树中
  68. ret+=sum[]*(segs[i+].h-segs[i].h);
  69. }
  70. printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T , ret);
  71. }
  72. return ;
  73. }

poj1511,线段树扫描线面积的更多相关文章

  1. HDU 1255 覆盖的面积 (线段树扫描线+面积交)

    自己YY了一个的写法,不过时间复杂度太高了,网上的想法太6了  题意:给你一些矩阵,求出矩阵的面积并 首先按照x轴离散化线段到线段树上(因为是找连续区间,所以段建树更加好做). 然后我们可以想一下怎样 ...

  2. HDU 3265 Posters (线段树+扫描线)(面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并. 其实一个中空矩形可以分成4个小的矩 ...

  3. [USACO18JAN] Lifeguards S (线段树:扫描线面积)

    扫描线裸题没什么好说的 注意空间不要开小了!!! #include <cstdio> #include <cstring> #include <algorithm> ...

  4. hdu 3265 Posters(线段树+扫描线+面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 题意:给你一张挖了洞的墙纸贴在墙上,问你总面积有多少. 挖了洞后其实就是多了几个矩形墙纸,一张墙 ...

  5. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

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

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

  7. hdu1255 覆盖的面积 线段树-扫描线

    矩形面积并 线段树-扫描线裸题 #include<stdio.h> #include<string.h> #include<algorithm> #include& ...

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

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

  9. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

随机推荐

  1. 51job_selenium测试2

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  2. NFS无法启动解决方式

    今天一台挂载nfs磁盘的服务器出现异常,数据不能写入,执行 df -h 卡住不动. 登录nfs server查看发现nfs为启动. [root@server10-13 web]# exportfs [ ...

  3. 函数和常用模块【day04】:内置函数(十)

    一.36-40 36.isinstance(object, classinfo) 功能:用于判断,对象是否是某个类的实例 # s = "alex" # 对象,"alex& ...

  4. UESTC - 1168 凤神与狗

    原题链接 凤神隐居山林,与猫狗为伴.起初,他拥有cc只猫和dd只狗.每天下午他随机从中选择一只出去游玩并且晚上归来.如果他带的是狗,则第二天早上狗的数量增加ww只,否则,猫的数量增加ww只.由于凤神特 ...

  5. 解决audio和video在手机端无法自动播放问题

    各大浏览器都为了节省流量,做出了优化,在用户没有行为动作时(交互)不予许自动播放 <audio src="music/bg.mp3" autoplay loop contro ...

  6. vue自学入门-3(vue第一个例子)

    1.安装后打开8080端口,http://localhost:8080/#/ 2.进入项目目录 2.默认路由 3.修改文件index.js 将Import HelloWorld一句修改为 import ...

  7. python初步学习-import和datetime模块

    模块 一个完整大型的python程序是由模块和包的形式组织起来的,可见模块在python中的重要性.模块是一种组织型式,它许多有关联(关系)的代码组织放到单独的独立文件中.简单的说,可以把模块理解为一 ...

  8. sybench压测下模拟误truncate数据恢复

    基本环境:官方社区版MySQL 5.7.21 Row+Gtid开启sysbench压测,使用mysqldump备份数据库,执行truncate操作,恢复数据到truncate前的时间点1.切换日志,记 ...

  9. 访问tp3.2的项目时出现No input file specified.的解决办法

    解决办法很简单如下: 打开.htaccess 在RewriteRule 后面的index.php教程后面添加一个“?” 原来的代码如下 <IfModule mod_rewrite.c> O ...

  10. mongodb系列~mongodb数据迁移

    一 简介:今天来聊聊mongo的数据迁移二 迁移   1 具体迁移命令   nohup mongodump --port --db dbname --collection tablename --qu ...