注意:本题的输入数据较多,推荐使用scanf读入数据.
2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
7.63 0.00
//
#include<stdio.h>
#include<algorithm>
#define MAXN 2015
using namespace std;
//坐标是浮点数
double y[MAXN*2];
struct lovekid{
double left,right,len,crossLen;
lovekid *leftSon,*rightSon;
int cover;
}tree[MAXN*2],*Root;
struct line{
double x,y1,y2;
int cover;
bool operator<(const line&t)const{
return x<t.x;
}
}point[MAXN*2];
int idx;
lovekid *CreatKid(){
lovekid *p;
p=&tree[idx++];
p->cover=0;
p->len=p->crossLen=0;
p->leftSon=NULL;
p->rightSon=NULL;
return p;
}
lovekid *CreatLoveKid(int left,int right){
lovekid *root=CreatKid();
root->left=y[left];
root->right=y[right];
if(right-left>1){
int mid=(left+right)>>1;
root->leftSon=CreatLoveKid(left,mid);
root->rightSon=CreatLoveKid(mid,right);
}
return root;
}
void GetLen(lovekid*root){
root->len=0;
if(root->cover>0)
root->len=root->right-root->left;
else if(root->leftSon!=NULL)
root->len=root->leftSon->len+root->rightSon->len;
}
void GetCrossLen(lovekid*root){
root->crossLen=0;
if(root->cover>1)
root->crossLen=root->right-root->left;
else if(root->leftSon!=NULL){
if(root->cover>0)
root->crossLen=root->leftSon->len+root->rightSon->len;
else root->crossLen=root->leftSon->crossLen+root->rightSon->crossLen;
}
}
void UpdateLen(lovekid*root){
GetLen(root);
GetCrossLen(root);
}
void Update(lovekid*root,line t){
if(root->left==t.y1&&root->right==t.y2){
root->cover+=t.cover;
UpdateLen(root);
return;
}
if(t.y1>=root->leftSon->right)
Update(root->rightSon,t);
else if(t.y2<=root->rightSon->left)
Update(root->leftSon,t);
else{
line tmp=t;
tmp.y2=root->leftSon->right;
Update(root->leftSon,tmp);
tmp=t;
tmp.y1=root->rightSon->left;
Update(root->rightSon,tmp);
}
UpdateLen(root);
}
int main(){
//freopen("C:\\Users\\loveKid\\Desktop\\in.txt","r",stdin);
int N,cas,i,j;
double x1,x2,y1,y2,ans;
scanf("%d",&cas);
while(cas--){
scanf("%d",&N);
idx=j=0;
ans=0;
for(i=0;i<N;i++,j+=2){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
point[j].x=x1;
point[j].y1=y1;
point[j].y2=y2;
point[j].cover=1;
y[j]=y1;
point[j+1].x=x2;
point[j+1].y1=y1;
point[j+1].y2=y2;
point[j+1].cover=-1;
y[j+1]=y2;
}
sort(y,y+j);
sort(point,point+j);
Root=CreatLoveKid(0,j-1);
Update(Root,point[0]);
for(i=1;i<j;i++){
ans+=Root->crossLen*(point[i].x-point[i-1].x);
Update(Root,point[i]);
}
printf("%.2lf\n",ans);
}
return 0;
}