hdu 1542 线扫描(线段树)+离散化 求覆盖面积

// hdu1542 

// 线扫瞄思想结合线段树求覆盖面积问题,也能求周长。具体如何线扫瞄 下面参考博客里面有

// 直接百度学的(想破脑壳也只能是wa或者tle)

// 参考博客  HDU 1542 Atlantis(线段树:扫描线)

// 不能算抄。。。结合了多方代码得出我喜欢的写法。。。离散化区间问题只停留在听懂的层面上, 之前并查集区间离散化也是囫囵吞枣的学,不能这样啊( ఠൠఠ )ノ

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define L k<<1
 4 #define R k<<1|1
 5 #define mid (tree[k].l+tree[k].r)>>1
 6 using namespace std;
 7 typedef long long ll;
 8 const int MAXN = 200+5;
 9 
10 double X[MAXN];
11 struct Edge {
12     double l, r;
13     double h;
14     int f;
15     Edge() {}
16     Edge(double l, double r, double h, int f):l(l),r(r),h(h),f(f) {}
17     bool operator < (const Edge &a) const {
18         return h < a.h;
19     }
20 }edge[MAXN];
21 //Edge ;
22 
23 struct segmemt_tree {
24     int l, r;// 左右区间端点
25     int cover;
26     double len;
27 }tree[4*MAXN+1];
28 
29 inline void build(int k, int l, int r) {
30     tree[k].l = l; tree[k].r = r;
31     tree[k].cover = tree[k].len = 0;
32     if(l == r) return ;
33     int m = mid;
34     build(L, l, m);
35     build(R, m+1, r);
36 }
37 
38 inline void push_up(int k) {
39     if(tree[k].cover) tree[k].len = X[tree[k].r+1] - X[tree[k].l];
40     else if(tree[k].l == tree[k].r) tree[k].len = 0;
41     else tree[k].len = tree[L].len + tree[R].len;
42 }
43 
44 inline void update(int k, int x, int y, int cover) {
45     if(tree[k].l >= x && tree[k].r <= y) {
46         tree[k].cover += cover;
47         push_up(k);
48         return ;
49     }
50     int m = mid;
51     if(x <= m) update(L, x, y, cover);
52     if(y > m) update(R, x, y, cover);
53     push_up(k);
54 }
55 
56 int main() {
57     int n, Case = 0;
58     while(scanf("%d", &n) == 1 && n) {
59         int cnt = 0;
60         double x1, y1, x2, y2;
61         for(int i = 0; i != n; ++i) {
62             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
63             X[cnt] = x1;
64             edge[cnt++] = Edge(x1, x2, y1, 1);
65             X[cnt] = x2;
66             edge[cnt++] = Edge(x1, x2, y2, -1);
67         }
68         sort(X, X+cnt);
69         sort(edge, edge+cnt);
70         int k = unique(X, X+cnt) - X;
71         build(1, 0, k-1);
72         double sum = 0;
73         for(int i = 0; i != cnt; ++i) {
74             int l = lower_bound(X, X+k, edge[i].l) - X;
75             int r = lower_bound(X, X+k, edge[i].r) - X - 1;
76             update(1, l, r, edge[i].f);
77             sum += (edge[i+1].h - edge[i].h) * tree[1].len;
78         }
79         printf("Test case #%d\n", ++Case);
80         printf("Total explored area: %.2lf\n\n", sum);
81     }
82     return 0;
83 }

 

猜你喜欢

转载自www.cnblogs.com/pupil-xj/p/11643843.html