矩形面积并

来源:互联网 发布:如何后加载js 编辑:程序博客网 时间:2024/06/09 20:21
#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;}


	
				
		
原创粉丝点击