# [HDOJ1255] 覆盖的面积（线段树，扫描线，矩形面积交）

 1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define lrt rt << 1
5 #define rrt rt << 1 | 1
6 typedef struct Seg {
7     double len, tlen;
8     int sign;
9 }Seg;
10 typedef struct Event {
11     double l, r, h;
12     int sign;
13 }Event;
14 const int maxn = 2100;
15 int n, hcnt;
16 vector<Event> event;
17 double h[maxn];
18 Seg seg[maxn<<2];
19
20 bool cmp(Event a, Event b) {
21     if(a.h != b.h) return a.h < b.h;
22     return a.sign > b.sign;
23 }
24
25 int id(double x) {
26     return lower_bound(h, h+hcnt, x) - h + 1;
27 }
28
29 void build(int l, int r, int rt) {
30     seg[rt].len = seg[rt].tlen = .0;
31     seg[rt].sign = 0;
32     if(l == r) return;
33     int mid = (l + r) >> 1;
34     build(l, mid, lrt);
35     build(mid+1, r, rrt);
36 }
37
38 void pushup(int l, int r, int rt) {
39     if(seg[rt].sign) {
40         seg[rt].len = h[r] - h[l-1];
41         if(seg[rt].sign > 1) seg[rt].tlen = seg[rt].len;
42         else seg[rt].tlen = seg[lrt].len + seg[rrt].len;
43     }
44     else {
45         if(l == r) seg[rt].len = seg[rt].tlen = 0;
46         else {
47             seg[rt].len = seg[lrt].len + seg[rrt].len;
48             seg[rt].tlen = seg[lrt].tlen + seg[rrt].tlen;
49         }
50     }
51 }
52
53 void update(int L, int R, int sign, int l, int r, int rt) {
54     if(L <= l && r <= R) {
55         seg[rt].sign += sign;
56         pushup(l, r, rt);
57         return;
58     }
59     int mid = (l + r) >> 1;
60     if(L <= mid) update(L, R, sign, l, mid, lrt);
61     if(mid < R) update(L, R, sign, mid+1, r, rrt);
62     pushup(l, r, rt);
63 }
64
65 int main() {
66     // freopen("in", "r", stdin);
67     int T;
68     double ax, ay, bx, by;
69     scanf("%d", &T);
70     while(T--) {
71         event.clear(); hcnt = 0;
72         scanf("%d", &n);
73         for(int i = 0; i < n; i++) {
74             scanf("%lf%lf%lf%lf",&ax,&ay,&bx,&by);
75             event.push_back(Event{ax,bx,ay,1});
76             event.push_back(Event{ax,bx,by,-1});
77             h[hcnt++] = ax, h[hcnt++] = bx;
78         }
79         sort(event.begin(), event.end(), cmp);
80         sort(h, h+hcnt); hcnt = unique(h, h+hcnt) - h;
81         build(1, hcnt, 1);
82         double ret = .0;
83         for(int i = 0; i < event.size(); i++) {
84             int l = id(event[i].l);
85             int r = id(event[i].r) - 1;
86             int sign = event[i].sign;
87             update(l, r, sign, 1, hcnt, 1);
88             ret += (event[i+1].h - event[i].h) * seg[1].tlen;
89         }
90         printf("%.2f\n", ret);
91     }
92     return 0;
93 }

posted @ 2017-05-05 14:47  Kirai  阅读(213)  评论(0编辑  收藏  举报