求面积交
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
#define maxn 11005
struct line
{
double x1,x2,h;
int c;
line(){}
line(double xx1,double xx2,double yy1,int cc):
x1(xx1),x2(xx2),h(yy1),c(cc){}
}s[maxn];
bool clm(line x,line y)
{
return x.h<y.h;
}
struct node
{
int l,r;
double len,len1;//len是该区间覆盖>1次的长度,len1是该区间覆盖等于一次的长度
int c;
}tree[maxn*4];
double x[maxn];
int n;
void build(int id,int l,int r)
{
tree[id].l=l;
tree[id].r=r;
tree[id].c=0;
tree[id].len=tree[id].len1=0.0;
if(l!=r)
{
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
}
void pushup(int id,int l,int r)
{
//先处理覆盖一次的长度
if(tree[id].c)tree[id].len1=x[r]-x[l-1];//若tree[id].c>=1说明该区间完全覆盖
else if(l==r)tree[id].len1=0.0;
else tree[id].len1=tree[id*2].len1+tree[id*2+1].len1;//若tree[id].c==0,覆盖一次的长度就左右儿子被覆盖一次的长度
//再处理覆盖两次以上的长度
if(tree[id].c>1)
tree[id].len=x[r]-x[l-1];
else if(l==r)tree[id].len=0.0;
else if(tree[id].c==1)//若tree[id].c==1,只能说明该区间没有被完全覆盖两次以上,有可能它的儿子覆盖了两次
tree[id].len=tree[id*2].len1+tree[id*2+1].len1;//去儿子节点覆盖了一次的长度
else
tree[id].len=tree[id*2].len+tree[id*2+1].len;//若tree[id].c==0它被覆盖了0次,但是它儿子可能被覆盖了两次以上,
//则去它儿子被覆盖两次以上的长度
}
void update(int id,int l,int r,int c)
{
//if(l<=tree[id].l&&tree[id].r<=r)
if(l==tree[id].l&&tree[id].r==r)
{
tree[id].c+=c;
pushup(id,tree[id].l,tree[id].r);
}
else
{
int mid=(tree[id].l+tree[id].r)/2;
if(r<=mid)update(id*2,l,r,c);
else if(l>mid)update(id*2+1,l,r,c);
else
{
update(id*2,l,mid,c);
update(id*2+1,mid+1,r,c);
}
// if(l<=mid)update(id*2,l,r,c);
// if(r>mid)update(id*2+1,l,r,c);
pushup(id,tree[id].l,tree[id].r);
}
}
int main()
{
int i,k,t;
double x1,x2,y1,y2;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
k=0;
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
s[k]=line(x1,x2,y1,1);
x[k]=x1;
k++;
s[k]=line(x1,x2,y2,-1);
x[k]=x2;
k++;
}
sort(s,s+k,clm);
sort(x,x+k);
int m=1;
for(i=1;i<k;i++)
{
if(x[i]!=x[i-1])
x[m++]=x[i];
}
build(1,1,m-1);
double ans=0.0;
for(i=0;i<k-1;i++)
{
int l=lower_bound(x,x+m-1,s[i].x1)-x;
int r=lower_bound(x,x+m-1,s[i].x2)-x;
update(1,l+1,r,s[i].c);
ans+=tree[1].len*(s[i+1].h-s[i].h);
}
printf("%0.2f\n",ans);
}
return 0;
}