线段树+扫面线 矩阵面积并
扫面线从下往上扫
将横坐标离散化 用线段树来进行区间更新
维护两个值cnt 和对应的有效的边(cnt>0)的长度
当有一个矩阵的下底边扫过的时候 对应的区间cnt+1
否则 对应的区间cnt-1
每次计算cnt > 0的区间长度 不会存在cnt < 0 的区间 因为上边扫描过之前必先扫描下底边
需要注意的是如何处理cnt和 len的关系
1 void push_up(int root, int l, int r) 2 { 3 if (seg[root].flag > 0) seg[root].len = hor[r+1] - hor[l]; 4 else if (l == r) seg[root].len = 0; 5 else seg[root].len = seg[lson(root)].len + seg[rson(root)].len; 6 }
这里对len的计算需要依据 flag(cnt)的值 而线段树并不要维护和、最小值之类的东西 不需要懒标记
更多关于矩阵面积并的细节
http://www.cnblogs.com/zhangmingcheng/p/3907072.html
代码君:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #include <string.h> 3 #include <iostream> 4 #include <stdio.h> 5 #define pb push_back 6 #define fi first 7 #define se second 8 #define lson(r) (r<<1) 9 #define rson(r) ((r<<1)|1) 10 11 using namespace std; 12 13 typedef long long ll; 14 15 const int MAXN = 1e3+7; 16 const int MAXV = 507; 17 const int MAXE = 507; 18 19 struct Seg 20 { 21 int flag; 22 double len; 23 }seg[MAXN << 2]; 24 struct Line 25 { 26 double h, px1, px2; 27 int x1, x2, flag; 28 Line () {} 29 Line (double px1, double px2, double h, int flag) : px1(px1), px2(px2), h(h), flag(flag) {} 30 bool operator < (Line l) const 31 { 32 return h < l.h; 33 } 34 }line[MAXN]; 35 int n; 36 double hor[MAXN]; 37 void push_up(int root, int l, int r) 38 { 39 if (seg[root].flag > 0) seg[root].len = hor[r+1] - hor[l]; 40 else if (l == r) seg[root].len = 0; 41 else seg[root].len = seg[lson(root)].len + seg[rson(root)].len; 42 } 43 void update(int root, int l, int r, int ul, int ur, int addval) 44 { 45 if (l > ur || r < ul) return ; 46 if (l >= ul && r <= ur) 47 { 48 seg[root].flag += addval; 49 push_up(root, l, r); 50 return ; 51 } 52 int mid = (l+r) >> 1; 53 update(lson(root), l, mid, ul, ur, addval); 54 update(rson(root), mid+1, r, ul, ur, addval); 55 push_up(root, l, r); 56 } 57 double query() 58 { 59 return seg[1].len; 60 } 61 int main() 62 { 63 //freopen("in.txt", "r", stdin); 64 int cas = 1; 65 while (cin >> n) 66 { 67 if (!n) break; 68 memset(line, 0, sizeof(line)); 69 memset(hor, 0, sizeof(hor)); 70 int num = 0; 71 for (int i = 0; i < n; i++) 72 { 73 double x1, x2, y1, y2; 74 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 75 line[num] = Line(x1, x2, y1, 1); 76 hor[num++] = x1; 77 line[num] = Line(x1, x2, y2, -1); 78 hor[num++] = x2; 79 } 80 sort(line, line+num); 81 sort(hor, hor+num); 82 int m = unique(hor, hor+num) - hor; 83 for (int i = 0; i < num; i++) 84 { 85 line[i].x1 = lower_bound(hor, hor+m, line[i].px1) - hor; 86 line[i].x2 = lower_bound(hor, hor+m, line[i].px2) - hor; 87 } 88 double prey = -1; 89 double ans = 0; 90 for (int i = 0; i < num; i++) 91 { 92 if (prey == -1) 93 { 94 prey = line[i].h; 95 update(1, 0, m-2, line[i].x1, line[i].x2-1, line[i].flag); 96 continue; 97 } 98 double det = line[i].h - prey; 99 double len = query(); 100 update(1, 0, m-2, line[i].x1, line[i].x2-1, line[i].flag); 101 prey = line[i].h; 102 ans += len*det; 103 } 104 printf("Test case #%d\nTotal explored area: %.2f\n\n", cas++, ans); 105 } 106 return 0; 107 }