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.
 

 

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.
 

 

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 }
View Code

 

posted on 2017-02-16 18:59  Jstyle  阅读(191)  评论(0编辑  收藏  举报

导航