掃面線從下往上掃html
將橫座標離散化 用線段樹來進行區間更新ios
維護兩個值cnt 和對應的有效的邊(cnt>0)的長度c++
當有一個矩陣的下底邊掃過的時候 對應的區間cnt+1ide
不然 對應的區間cnt-1spa
每次計算cnt > 0的區間長度 不會存在cnt < 0 的區間 由於上邊掃描過以前必先掃描下底邊code
須要注意的是如何處理cnt和 len的關係htm
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)的值 而線段樹並不要維護和、最小值之類的東西 不須要懶標記blog
更多關於矩陣面積並的細節ci
http://www.cnblogs.com/zhangmingcheng/p/3907072.htmlstring
代碼君:
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 }