取出纵向边按x坐标排序,在y方向上建立线段树。

每次查询当前有效长度len,ans += len*(x[i]-x[i-1]); 其中len为T[rt].len;

查询完毕后更新y方向上线段树,入边+1, 出边-1。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define lson l, m, rt<<1
  4. #define rson m+1, r, rt<<1|1
  5. typedef long long ll;
  6. struct L{
  7. double x, y1, y2;
  8. int d;
  9. L(){}
  10. L(double x, double y1, double y2, int d): x(x), y1(y1), y2(y2), d(d){}
  11. };
  12. L line[];
  13. bool cmp(L A, L B){
  14. return A.x < B.x;
  15. }
  16. double y[];
  17.  
  18. struct Node{
  19. int d;
  20. double len;
  21. };
  22. Node T[<<];
  23. void init(){
  24. memset(T, , sizeof(T));
  25. }
  26. void pushup(int rt, int l, int r){
  27. if(T[rt].d)
  28. T[rt].len = y[r]-y[l-];
  29. else
  30. T[rt].len = l == r? : T[rt<<].len+T[rt<<|].len;
  31. }
  32. void update(int L, int R, int d, int l, int r, int rt){
  33. if(L <= l&&r <= R){
  34. T[rt].d += d;
  35. pushup(rt, l , r);
  36. return ;
  37. }
  38. int m = (l+r)>>;
  39. if(L <= m) update(L, R, d, lson);
  40. if(R > m) update(L, R, d, rson);
  41. pushup(rt, l, r);
  42. }
  43.  
  44. int main(){
  45. int n, ca = ;
  46. double x1, y1, x2, y2;
  47. while(scanf("%d", &n), n){
  48. for(int i = ; i < n; i++){
  49. scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
  50. line[i*] = L(x1, y1, y2, );
  51. line[i*+] = L(x2, y1, y2, -);
  52. y[i*] = y1, y[i*+] = y2;
  53. }
  54. sort(line, line+*n, cmp);
  55. sort(y, y+*n);
  56.  
  57. init();
  58. double ans = ;
  59. for(int i = ; i < *n; i++){
  60. if(i&&line[i].x != line[i-].x)
  61. ans += (line[i].x-line[i-].x)*T[].len;
  62. int l = lower_bound(y, y+*n, line[i].y1)-y+, r = lower_bound(y, y+*n, line[i].y2)-y;
  63. if(l <= r)
  64. update(l, r, line[i].d, , *n, );
  65. }
  66. printf("Test case #%d\n", ca++);
  67. printf("Total explored area: %.2f\n\n", ans);
  68. }
  69. return ;
  70. }

无pushdown()函数,每条线段只存一次。d表示被覆盖的次数,len表示至少被覆盖一次的合法长度。详见pushup()函数。

ans += T[1].len*(x[i]-x[i-1]);

求面积交:方法同求面积并,外加len2表示至少被覆盖两次的合法长度,ans += T[1].len2*(x[i]-x[i-1]);

求周长并:方法同面积并,扫描两次,分别沿x方向和y方向,每次加上  更新前后T[1].len的差值的绝对值。

HDU1542矩形面积并的更多相关文章

  1. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  2. HDU1542 扫描线(矩形面积并)

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

  3. 【hdu1542】线段树求矩形面积并

    分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...

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

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

  5. [LeetCode] Rectangle Area 矩形面积

    Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...

  6. POJ 1151 Atlantis(线段树-扫描线,矩形面积并)

    题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...

  7. 25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有

    package zhongqiuzuoye; //自己写的方法 public class Rect { public double width; public double height; Rect( ...

  8. 扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage

    Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit user ...

  9. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

    求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...

随机推荐

  1. MySQL与SQL比较有那些区别呢

    MySQL是一个逐渐完善的过程,使用前期版本时会遇到一些问题,通常搞得莫名其妙,在版本选择上尽量选择最新的. 1.在5.03以前版本中,存储varchar型数据时,后面的空格会被忽视掉,前面的空格会保 ...

  2. 删除ecshop登录后台看到的系统信息

    登陆ecshop后台,默认打开在页面顶部会出现个系统信息,显示操作系统,数据库版本,以及安装日期系统版本号.部分客户问到怎么删除,这里最模板提供ecshop教程告诉大家方法. 找到admin\temp ...

  3. Oracle存储过程返回游标实例详解

    复制代码 代码如下:CREATE OR REPLACE PROCEDURE PROCSENDEMAIL(P_TXT VARCHAR2, P_SUB VARCHAR2, P_SENDOR VARCHAR ...

  4. [Ogre][地形][原创]基于OgreTerrain的地形实现

    需要用到的外部图片资源: 在ogre调用时需要多用到的几个外部dll: OgreTerrain_d.dll 需要添加头文件 #include "Ogre\Ogre.h"#inclu ...

  5. python: linux下安装redis

    Python连接时报拒绝连接,需要重装redis: 1) 卸载redis sudo apt-get remove redis-server sudo apt-get autoremove 2)编译安装 ...

  6. ACM题目————士兵杀敌(三)

    [RMQ算法]:用于当数组过于庞大的时候,查询区间的最大(最小)值. 时间复杂度:O(nlogn),主要时间发费在预处理上,查询只要O(1). 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军 ...

  7. C/C++获取数组的长度

    C.C++中没有提供 直接获取数组长度的函数,对于存放字符串的字符数组提供了一个strlen函数获取长度,那么对于其他类型的数组如何获取他们的长度呢?其中一种方法是使 用sizeof(array) / ...

  8. 浪首登录浮层增加收藏入口项目学到的几点知识-IE7 bug、relatedTarget、字符串换行

    这两天做这个项目略有收获,记录如下: 1. 项目中有个bug,在IE7中登录成功时下拉菜单没有展开的情况下总有个残影在页面中,如下图所示: 通过多种方法都没有解决,后来才知道原来是在IE中displa ...

  9. 覆盖率测试工具gcov的前端工具_LCOV

    http://my.oschina.net/alphajay/blog/33725 1.Gcov是进行代码运行的覆盖率统计的工具,它随着gcc的发布一起发布的,它的使用也很简单,需要在编译和链接的时候 ...

  10. UVa(11292),贪心水题

    蓝书P1, 很简单的一个贪心选择,用能力小的去砍小的.本来想双重循环,哎,傻逼了,直接遍历选手,碰到能砍的就砍掉. #include <stdio.h> #include <algo ...