// 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 }