【HDOJ】1542 Atlantis
离散化+线段树+扫描线,求覆盖面积。
1 /* 1542 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 typedef struct segment_t { 43 double l, r, h; 44 int f; 45 46 friend bool operator< (const segment_t& a, const segment_t& b) { 47 return a.h < b.h; 48 } 49 50 } segment_t; 51 52 typedef struct { 53 int l, r, c; 54 double len; 55 } node_t; 56 57 const int maxn = 205; 58 double X[maxn]; 59 segment_t seg[maxn]; 60 node_t nd[maxn<<2]; 61 62 void build(int l, int r, int rt) { 63 nd[rt].l = l; 64 nd[rt].r = r; 65 nd[rt].c = 0; 66 nd[rt].len = 0; 67 68 if (l == r) 69 return ; 70 71 int mid = (l + r) >> 1; 72 build(lson); 73 build(rson); 74 } 75 76 void PushUp(int rt) { 77 if (nd[rt].c) 78 nd[rt].len = X[nd[rt].r+1] - X[nd[rt].l]; 79 else if (nd[rt].r == nd[rt].l) 80 nd[rt].len = 0; 81 else 82 nd[rt].len = nd[rt<<1].len + nd[rt<<1|1].len; 83 } 84 85 void update(int L, int R, int delta, int rt) { 86 if (L<=nd[rt].l && nd[rt].r<=R) { 87 nd[rt].c += delta; 88 PushUp(rt); 89 return ; 90 } 91 92 int mid = (nd[rt].l + nd[rt].r) >> 1; 93 94 if (mid >= R) { 95 update(L, R, delta, rt<<1); 96 } else if (mid < L) { 97 update(L, R, delta, rt<<1|1); 98 } else { 99 update(L, R, delta, rt<<1); 100 update(L, R, delta, rt<<1|1); 101 } 102 103 PushUp(rt); 104 } 105 106 int main() { 107 ios::sync_with_stdio(false); 108 #ifndef ONLINE_JUDGE 109 freopen("data.in", "r", stdin); 110 freopen("data.out", "w", stdout); 111 #endif 112 113 int n, m, xn; 114 double x1, x2, y1, y2; 115 double ans; 116 int L, R; 117 int tt = 0; 118 119 while (scanf("%d",&n)!=EOF && n) { 120 ans = 0.; 121 m = 0; 122 rep(i, 0, n) { 123 scanf("%lf %lf %lf %lf", &x1,&y1,&x2,&y2); 124 seg[m].l = seg[m+1].l = x1; 125 seg[m].r = seg[m+1].r = x2; 126 seg[m].h = y1; 127 seg[m].f = 1; 128 seg[m+1].h = y2; 129 seg[m+1].f = -1; 130 131 X[m] = x1; 132 X[m+1] = x2; 133 134 m += 2; 135 } 136 137 sort(seg, seg+m); 138 sort(X, X+m); 139 xn = unique(X, X+m)-X; 140 141 build(0, xn-1, 1); 142 143 rep(i, 0, m) { 144 L = lower_bound(X, X+xn, seg[i].l) - X; 145 R = lower_bound(X, X+xn, seg[i].r) - X - 1; 146 update(L, R, seg[i].f, 1); 147 ans += (seg[i+1].h - seg[i].h) * nd[1].len; 148 #ifndef ONLINE_JUDGE 149 printf("L = %d, R = %d, len = %.2lf\n", L, R, nd[1].len); 150 #endif 151 } 152 153 printf("Test case #%d\n", ++tt); 154 printf("Total explored area: %.02lf\n\n", ans); 155 } 156 157 #ifndef ONLINE_JUDGE 158 printf("time = %d.\n", (int)clock()); 159 #endif 160 161 return 0; 162 }