HDU - 1542【离散化+线段树+扫描线】
Atlantis
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11997 Accepted Submission(s): 5056
Problem Description
There
are several ancient Greek texts that contain descriptions of the fabled
island Atlantis. Some of these texts even include maps of parts of the
island. But unfortunately, these maps describe different regions of
Atlantis. Your friend Bill has to know the total area for which maps
exist. You (unwisely) volunteered to write a program that calculates
this quantity.
Input
The
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.
The input file is terminated by a line containing a single 0. Don’t process it.
Output
For
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.
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
题意:
给你每个矩形的左下和右上的点,让你求面积并。
题解:
裸地扫描线+线段树维护区间和。我是从左往右扫,因此离散化的是y坐标。注意区间更新的时候,因为点数为cnt的点实际上维护的是长度为cnt-1的区间,
因此更新的时候是 pos1+1, pos2;
当时在学校认真思考了一早上,一直懒得补,今天写了之后发现离散化写的很烦,自己太挫了,后来发现别人的很清晰,就拿来用了。
代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <cmath> 4 #include <cstring> 5 #include <map> 6 #include <vector> 7 #include <queue> 8 #include <list> 9 #include <cstdio> 10 #define rep(i,a,b) for(int (i) = (a);(i) <= (b);++ (i)) 11 #define per(i,a,b) for(int (i) = (a);(i) >= (b);-- (i)) 12 #define mem(a,b) memset((a),(b),sizeof((a))) 13 #define FIN freopen("in.txt","r",stdin) 14 #define FOUT freopen("out.txt","w",stdout) 15 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 16 #define mid ((l+r)>>1) 17 #define ls (id<<1) 18 #define rs ((id<<1)|1) 19 #define INF 0x3f3f3f3f 20 typedef long long ll; 21 const ll mod = 1e8+7; 22 const ll eps = 1e-12; 23 using namespace std; 24 const int N = 210; 25 26 int n; 27 double xp1, yp1, xp2, yp2, y[N*4]; 28 struct Line{ 29 double x, y1, y2; 30 int f; 31 bool operator < (const Line &r) const { 32 return x < r.x; 33 } 34 }hashy[N*4]; 35 struct Node{ 36 double sum; 37 int lazy; 38 }node[N*4]; 39 40 void pushUp(int id, int l, int r){ 41 if(node[id].lazy > 0) node[id].sum = y[r-1]-y[l-2]; 42 else if(l == r) node[id].sum = 0; 43 else 44 node[id].sum = node[ls].sum+node[rs].sum; 45 } 46 void build(int id, int l, int r){ 47 node[id].lazy = 0; 48 if(l == r){ 49 node[id].sum = 0; 50 return ; 51 } 52 build(ls, l, mid); 53 build(rs, mid+1, r); 54 } 55 void update(int id, int l, int r, int ql, int qr, int p){ 56 if(ql == l && qr == r){ 57 node[id].lazy += p; 58 pushUp(id, l, r); 59 return ; 60 } 61 if(qr <= mid) update(ls, l, mid, ql, qr, p); 62 else if(ql > mid) 63 update(rs, mid+1, r, ql, qr, p); 64 else{ 65 update(ls, l, mid, ql, mid, p); 66 update(rs, mid+1, r, mid+1, qr, p); 67 } 68 pushUp(id, l, r); 69 } 70 int main() 71 { 72 //FIN; 73 int w_w = 0; 74 while(cin >> n, n != 0){ 75 int len = 0; 76 rep(i, 1, n){ 77 cin >> xp1 >> yp1 >> xp2 >> yp2; 78 hashy[len].x = xp1; hashy[len].y1 = yp1; 79 hashy[len].y2 = yp2; hashy[len].f = 1; y[len++] = yp1; 80 hashy[len].x = xp2; hashy[len].y1 = yp1; 81 hashy[len].y2 = yp2; hashy[len].f = -1; y[len++] = yp2; 82 } 83 sort(hashy, hashy+len); 84 sort(y, y+len); 85 86 build(1, 1, n*2); 87 double ans = 0; 88 rep(i, 0, len-1){ 89 int pos1 = lower_bound(y, y+len, hashy[i].y1)-y+1; 90 int pos2 = lower_bound(y, y+len, hashy[i].y2)-y+1; 91 if(i) ans += node[1].sum*(hashy[i].x-hashy[i-1].x); 92 update(1, 1, n*2, pos1+1, pos2, hashy[i].f); 93 //cout << "sum: " << node[1].sum << endl; 94 } 95 cout << "Test case #" << ++w_w << endl; 96 printf("Total explored area: %.2lf\n\n", ans); 97 } 98 return 0; 99 }