1 /*
2 题意:矩形面积并
3
4 分析:离散+线段树+扫描线;
5
6 细节:首先线段记录的信息,len[]表示区间被覆盖的长度,cov[]表示当前区间是否被完全覆盖
7 其次,线段树的叶子节点[l,r]{l==r}的长度是?区间[l,r]的长度是LX[r]-LX[l]{LX是离散后保存数据的地方}
8 那叶子节点[l,l]的长度不就变成0,显然这是有问题的
9
10 线段树的每一个节点表示一段区间,[l,r]该区间表示LX[r+1]-LX[l]的长度
11 1___2___3___4___5离散后的状况
12 1 2 3 4 线段树中的每一个节点
13
14
15
16 */
17 #include<cstdio>
18 #include<cstring>
19 #include<cmath>
20 #include<iostream>
21 #include<algorithm>
22 #include<cstdlib>
23 #include<vector>
24 #include<string>
25 #define Find(i) lower_bound(LX.begin(),LX.begin()+n1,i)-LX.begin()
26 #define lson l,m,rt<<1
27 #define rson m+1,r,rt<<1|1
28 using namespace std;
29 const int N=200+10;
30 struct Edge{
31 double hi,ls,rs;
32 int s;
33 Edge(){}
34 Edge(double a,double b,double c,int e):hi(a),ls(b),rs(c),s(e){}
35 bool operator < (const Edge &p)const{
36 return hi<p.hi;
37 }
38 };
39 vector<Edge> E;
40 vector<double> LX;
41 double len[N<<2];
42 int cov[N<<2];//表示区间是否被完全覆盖
43 int n,n1;
44 void pushup(int l,int r,int rt){
45 if (cov[rt]>=1){
46 len[rt]=(LX[r+1]-LX[l]);
47 }else if (l==r) len[rt]=0;
48 else len[rt]=len[rt<<1]+len[rt<<1|1];
49 }
50 void update(int L,int R,int v,int l,int r,int rt){
51 if (L<=l && r<=R){
52 cov[rt]+=v;
53 if (cov[rt]>=1) len[rt]=(LX[r+1]-LX[l]);
54 else if (l==r) len[rt]=0;
55 else len[rt]=len[rt<<1]+len[rt<<1|1];
56 return ;
57 }
58 int m=(l+r)>>1;
59 if (L<=m) update(L,R,v,lson);
60 if (m< R) update(L,R,v,rson);
61 pushup(l,r,rt);
62 }
63
64 void work(){
65 double ret=0;
66 memset(len,0,sizeof(len));
67 memset(cov,0,sizeof(cov));
68 for (int i=0;i<E.size();i++){
69 int l=Find(E[i].ls),r=Find(E[i].rs)-1;
70 if (l<=r) update(l,r,E[i].s,0,n1-1,1);
71 if (E[i].hi!=E[i+1].hi){
72 ret+=len[1]*(E[i+1].hi-E[i].hi);
73 }
74 }
75 printf("Total explored area: %.2lf\n",ret);
76
77 }
78 int main(){
79 int cas=0;
80 while (~scanf("%d",&n),n){
81 E.clear();LX.clear();
82 for (int i=0;i<n;i++){
83 double x,y,x2,y2;
84 scanf("%lf%lf%lf%lf",&x,&y,&x2,&y2);
85 E.push_back(Edge(y,x,x2,1));
86 E.push_back(Edge(y2,x,x2,-1));
87 LX.push_back(x);LX.push_back(x2);
88 }
89 sort(E.begin(),E.end());
90 sort(LX.begin(),LX.end());
91 n1=unique(LX.begin(),LX.end())-LX.begin();
92 printf("Test case #%d\n",++cas);
93 work();
94 printf("\n");
95 }
96 return 0;
97 }