#include <iostream> #include <vector> #include <algorithm> #include<cstdio> using namespace std; typedef double Type; #define ll double #define maxn 200200 // 垂直线段 struct VLine { Type x; Type y1, y2; int val; VLine() {} VLine(Type _x, Type _y1, Type _y2,int _v) { x = _x; y1 = _y1; y2 = _y2; val = _v; } }; vector <VLine> Vl; bool cmp(VLine a, VLine b) { return a.x < b.x; } // 矩形 struct Rectangle { Type x0, y0, x1, y1; Rectangle() {} Rectangle(Type _x0, Type _y0, Type _x1, Type _y1) { x0 = _x0; y0 = _y0; x1 = _x1; y1 = _y1; } }; vector <Rectangle> Rec; double tmp[maxn]; int tmpsize; double bin[maxn]; int size; struct Tree { int p; int l, r; int nCover; // 被完全覆盖的次数 Type ylen; // 矩形并测度 Type yylen; // 矩形交测度 void Update1();// 矩形并的向上更新 void Update2();// 矩形交的向上更新 int Mid() { return (l + r) >> 1; } }T[maxn*4]; void Tree::Update1() { if(nCover > 0) ylen = bin[r] - bin[l]; else if(l + 1 == r) ylen = 0; else ylen = T[p<<1].ylen + T[p<<1|1].ylen; } void Tree::Update2() { if(nCover >=2) yylen = bin[r] - bin[l]; else if(l + 1 == r) yylen = 0; else if(nCover==1) yylen=T[p<<1].ylen+T[p<<1|1].ylen; else yylen=T[p<<1].yylen+T[p<<1|1].yylen; } void Build(int p, int l, int r) { T[p].l = l;T[p].r = r;T[p].p = p;T[p].ylen = T[p].nCover = 0; if(l + 1 == r || l == r) return ; int mid = (l + r) >> 1; Build(p<<1, l, mid); Build(p<<1|1, mid, r); } void Insert(int p, int l, int r, int val) { if(l <= T[p].l && T[p].r <= r) { T[p].nCover += val; T[p].Update1(); T[p].Update2(); return ; } int mid = T[p].Mid(); if(l < mid) Insert(p<<1, l, r, val); if(mid < r) Insert(p<<1|1, l, r, val); T[p].Update1(); T[p].Update2(); } void ProcessBinArray() { sort(tmp, tmp +tmpsize); bin[size = 1] = tmp[0]; for(int i = 1; i <tmpsize ;i++) { if(tmp[i] != tmp[i-1]) bin[++size] = tmp[i]; } } int Binary(Type v) { int l = 1; int r = size; while(l <= r) { int m = (l + r) >> 1; if(bin[m] == v) return m; if(v > bin[m]) l = m + 1; else r = m - 1; } } int main() { int n; int i, j; Type x[4], y[4]; int ca;scanf("%d",&ca); while(ca--) { scanf("%d", &n); Rec.clear(); Vl.clear(); tmpsize = 0; for(i = 0; i < n; i++) { for(j = 0; j < 2; j++) { scanf("%lf %lf", &x[j], &y[j]); tmp[ tmpsize++ ] = y[j]; } Rec.push_back(Rectangle(x[0], y[0], x[1], y[1])); } ProcessBinArray(); for(i = 0; i < Rec.size(); i++) { Rectangle& rt = Rec[i]; if(rt.x0 == rt.x1 || rt.y0 == rt.y1) continue; int y0 = Binary(rt.y0); int y1 = Binary(rt.y1); Vl.push_back(VLine(rt.x0, y0, y1, 1)); Vl.push_back(VLine(rt.x1, y0, y1, -1)); } sort(Vl.begin(), Vl.end(), cmp); Build(1, 1, size); ll ans = 0; for(i = 0; i < Vl.size(); i++) { if(i) { ans += (ll)(Vl[i].x - Vl[i-1].x) * T[1].yylen; } Insert(1, Vl[i].y1, Vl[i].y2, Vl[i].val); } printf("%.2lf\n", ans); } return 0; }
矩形面积并
最新推荐文章于 2022-03-29 20:42:03 发布