/* 扫描线求矩阵的覆盖面 离散化 线段树求面积并升级版 */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) typedef long long LL; const int maxn = 10005; int cnt,ret; struct Seg{ double a,b,h; int c; Seg(double a = 0,double b = 0,double h = 0,int c = 0): a(a),b(b),h(h),c(c){}; friend bool operator < (Seg p,Seg q){ return p.h < q.h; } }seg[maxn]; double Hash[maxn]; int HASH(double t){ return lower_bound(Hash,Hash + ret,t) - Hash; } void Hash_init(){ sort(Hash,Hash + ret); ret = unique(Hash,Hash + ret) - Hash; } struct Node{ int l,r,col; double s,ss; int mid(){ return (l + r) >> 1; } double len(){ return Hash[r + 1] - Hash[l]; } }node[maxn << 2]; void build(int l,int r,int pos){ node[pos].l = l; node[pos].r = r; node[pos].col = 0; node[pos].ss = node[pos].s = 0; if(l == r) return; int mid = node[pos].mid(); build(l,mid,lson); build(mid + 1,r,rson); } void pushup(int pos){ if(node[pos].col){ node[pos].s = node[pos].len(); } else if(node[pos]. l == node[pos].r){ node[pos].s = 0; } else{ node[pos].s = node[lson].s + node[rson].s; } if(node[pos].col > 1){ node[pos].ss = node[pos].len(); } else if(node[pos].l == node[pos].r){ node[pos].ss = 0; } else if(node[pos].col == 1){ node[pos].ss = node[lson].s + node[rson].s; } else{ node[pos].ss = node[lson].ss + node[rson].ss; } } void update(int l,int r,int pos,int d){ if(l <= node[pos].l && node[pos].r <= r){ node[pos].col += d; pushup(pos); return; } int mid = node[pos].mid(); if(l <= mid) update(l,r,lson,d); if(r > mid) update(l,r,rson,d); pushup(pos); } int main(){ int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); cnt = 0; ret = 0; double a,b,c,d; for(int i = 0; i < n; i++){ scanf("%lf%lf%lf%lf",&a,&b,&c,&d); seg[cnt++] = Seg(a,c,b,1); seg[cnt++] = Seg(a,c,d,-1); Hash[ret++] = a; Hash[ret++] = c; } Hash_init(); sort(seg,seg + cnt); build(0,ret,1); double ans = 0; for(int i = 0; i < cnt - 1; i++){ int l = HASH(seg[i].a),r = HASH(seg[i].b) - 1,c = seg[i].c; update(l,r,1,c); ans += node[1].ss * (seg[i + 1].h - seg[i].h); } printf("%.2f\n",ans); } return 0; } /* 1 2 0 0 1 1 0 0 1 1 */