Atlantis HDU - 1542
InputThe input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don’t process it.OutputFor each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
题解:线段树维护的是算面积时的有效宽。
明白了线段树维护的是啥,剩下的就是理解代码了。。。感谢前辈们的贡献。
1 #pragma warning(disable:4996) 2 #include<cstdio> 3 #include<stack> 4 #include<cmath> 5 #include<string> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 using namespace std; 10 11 #define lson root<<1 12 #define rson root<<1|1 13 #define ll long long 14 15 const int maxn = 666; 16 17 int n, cnt[maxn]; 18 double Hash[maxn], sum[maxn]; 19 20 struct Seg { 21 int d; 22 double l, r, h; 23 Seg(){} 24 Seg(double l, double r, double h, int d): l(l), r(r), h(h), d(d) {} 25 bool operator<(const Seg& rhs)const { return h < rhs.h; } 26 }line[maxn]; 27 28 void Push_up(int l, int r, int root) { 29 if (cnt[root]) sum[root] = Hash[r] - Hash[l]; //如果区间被全部覆盖了,直接赋值 30 else if (l + 1 == r) sum[root] = 0; //如果区间没有被覆盖且是叶子区间,直接赋0 31 else sum[root] = sum[lson] + sum[rson]; //如果区间没有被覆盖但不是叶子区间。为什么这样做呢?因为它的子区间可能被覆盖了,所以等于左区间加上右区间。 32 } 33 34 void Update(int L, int R, int l, int r, int root, int c) { 35 if (l >= R || r <= L) return; //和点组成的线段树不同(点组成的线段树:if(l>R || r<L) return;) 36 if (L <= l && r <= R) { 37 cnt[root] += c; 38 Push_up(l, r, root); 39 return; 40 } 41 int mid = (l + r) >> 1; 42 Update(L, R, l, mid, lson, c); 43 Update(L, R, mid, r, rson, c); 44 Push_up(l, r, root); 45 } 46 47 int main() 48 { 49 int kase = 0; 50 while (scanf("%d", &n) && n) { 51 double x1, y1, x2, y2; 52 for (int i = 1; i <= n; i++) { 53 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 54 line[i] = Seg(x1, x2, y1, 1); 55 line[i + n] = Seg(x1, x2, y2, -1); 56 Hash[i] = x1; 57 Hash[i + n] = x2; 58 } 59 n <<= 1; 60 sort(line + 1, line + n + 1); 61 sort(Hash + 1, Hash + n + 1); 62 63 int m = unique(Hash + 1, Hash + n + 1) - (Hash + 1); 64 65 66 memset(sum, 0, sizeof(sum)); 67 memset(cnt, 0, sizeof(cnt)); 68 69 double ans = 0; 70 for (int i = 1; i < n; i++) { 71 int l = lower_bound(Hash + 1, Hash + m + 1, line[i].l) - Hash; 72 int r = lower_bound(Hash + 1, Hash + m + 1, line[i].r) - Hash; 73 74 Update(l, r, 1, m, 1, line[i].d); 75 ans += sum[1] * (line[i + 1].h - line[i].h); 76 } 77 printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++kase, ans); 78 } 79 return 0; 80 }