典型的线段树+线扫描
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define nn 1010
struct node
{
int l,r,c;
double len1,len2;
}tree[nn<<3];
struct seg
{
double l,r,h;
int f;
}s[nn<<1];
double pos[nn<<1];
bool cmp(seg a,seg b)
{
return a.h<b.h;
}
int binary(double c,int low,int top)
{
while(low<=top)
{
int mid=(low+top)>>1;
if(pos[mid]==c) return mid;
else if(pos[mid]>c) top=mid;
else low=mid+1;
}
return -1;
}
void build(int ll,int rr,int rt)
{
tree[rt].l=ll; tree[rt].r=rr; tree[rt].c=0;
if(ll==rr) return;
int mid=(ll+rr)>>1;
build(ll,mid,rt<<1);
build(mid+1,rr,rt<<1|1);
}
void getlen(int rt)
{
if(tree[rt].c)
tree[rt].len1=pos[tree[rt].r+1]-pos[tree[rt].l];
else if(tree[rt].r==tree[rt].l)
tree[rt].len1=0;
else
tree[rt].len1=tree[rt<<1].len1+tree[rt<<1|1].len1;
if(tree[rt].c>=2)
tree[rt].len2=pos[tree[rt].r+1]-pos[tree[rt].l];
else if(tree[rt].r==tree[rt].l)
tree[rt].len2=0;
else if(tree[rt].c==1)//如果该点被更新一次,则等于儿子被更新一次以上的长度和;
tree[rt].len2=tree[rt<<1].len1+tree[rt<<1|1].len1;
else
tree[rt].len2=tree[rt<<1].len2+tree[rt<<1|1].len2;
}
void updata(int ll,int rr,int v,int rt)
{
if(tree[rt].l==ll && tree[rt].r==rr)
{
tree[rt].c+=v;
getlen(rt);
return;
}
int mid=(tree[rt].l+tree[rt].r)>>1;
if(rr<=mid)
updata(ll,rr,v,rt<<1);
else if(ll>mid)
updata(ll,rr,v,rt<<1|1);
else
{
updata(ll,mid,v,rt<<1);
updata(mid+1,rr,v,rt<<1|1);
}
getlen(rt);
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int num=0;
for(int i=0;i<n;i++)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
s[num].l=x1; s[num].r=x2; s[num].h=y1; s[num].f=1;
s[num+1].l=x1; s[num+1].r=x2; s[num+1].h=y2; s[num+1].f=-1;
pos[num]=x1; pos[num+1]=x2;
num+=2;
}
sort(pos,pos+num);
sort(s,s+num,cmp);
int m=1;
for(int i=1;i<num;i++)
if(pos[i]!=pos[i-1])
pos[m++]=pos[i];
/*for(int i=0;i<m;i++)
printf("%.2lf ",pos[i]);
printf("\n");
for(int i=0;i<num;i++)
printf("%.2lf %.2lf %.2lf\n",s[i].l,s[i].r,s[i].h);
printf("\n");*/
build(0,m-1,1);
double ans=0.0;
for(int i=0;i<num;i++)
{
int l=binary(s[i].l,0,m-1);
int r=binary(s[i].r,0,m-1)-1;
//printf("%d %d\n",l,r);
updata(l,r,s[i].f,1);
//printf("A\n");
ans+=(s[i+1].h-s[i].h)*tree[1].len2;
//printf("%.2lf\n",tree[1].len2);
}
printf("%.2lf\n",ans);
}
return 0;
}