線段樹+掃面線 矩陣面積並

掃面線從下往上掃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 }
View Code
相關文章
相關標籤/搜索