hdu1255 线段树+扫描线计算矩形面积交

hdu1255 覆盖的面积
传送门

题意

平面上给出\(n(1\leq n\leq 1000)\)个矩形,每个矩形的左下角坐标为\((x_1,y_1)\),右上角坐标为\((x_2,y_2)\)\(x_1,y_1,x_2,y_2\)均为实数,计算被这些矩形覆盖过至少两次的区域的面积。

题解

线段树+扫描线
在矩形面积并的基础上做出修改
离散化\(x\)坐标,扫描线从下向上扫描
线段树节点维护三个信息:
cnt:区间被覆盖的次数(标记不下传)
s:区间被覆盖至少一次的实际长度
ss:区间被覆盖至少两次的实际长度

#include <bits/stdc++.h>
#define LL long long
#define PII pair<int,int>
#define PLI pair<LL,int>
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define lowbit(x) (x&(-x))
using namespace std;

const int maxn=1010;
int T,n,m,k;
double X[2*maxn];

struct node{
    double l,r,h;
    int state;
    node(){}
    node(double l,double r,double h,int state):l(l),r(r),h(h),state(state){}
    bool operator < (const node& t)const{
        return h<t.h;
    }
}nodes[2*maxn];

struct SGT{
    int cnt;
    double s,ss;
}sgt[8*maxn];

int binary_search(double x){
    int l=1,r=k;
    while(r>=l){
        int mid=(l+r)>>1;
        if(X[mid]==x) return mid;
        if(X[mid]>x) r=mid-1;
        else l=mid+1;
    }
    return -1;
}

void build(int o,int l,int r){
    sgt[o].cnt=sgt[o].s=sgt[o].ss=0;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
}

void pushup(int o,int l,int r){
    if(sgt[o].cnt) sgt[o].s=X[r+1]-X[l];
    else if(l==r) sgt[o].s=0;
    else sgt[o].s=sgt[o<<1].s+sgt[o<<1|1].s;
    if(sgt[o].cnt>1) sgt[o].ss=X[r+1]-X[l];
    else if(l==r) sgt[o].ss=0;
    else if(sgt[o].cnt==1) sgt[o].ss=sgt[o<<1].s+sgt[o<<1|1].s;
    else sgt[o].ss=sgt[o<<1].ss+sgt[o<<1|1].ss;
}

void update(int o,int l,int r,int ql,int qr,int v){
    if(ql<=l && r<=qr){
        sgt[o].cnt+=v;
        pushup(o,l,r);
        return;
    }
    int mid=(l+r)>>1;
    if(ql<=mid) update(lson,ql,qr,v);
    if(qr>mid) update(rson,ql,qr,v);
    pushup(o,l,r);
}

int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        m=1;
        for(int i=1;i<=n;i++,m+=2){
            double l,r,h1,h2;
            scanf("%lf %lf %lf %lf",&l,&h1,&r,&h2);
            nodes[m]=node(l,r,h1,1);
            nodes[m+1]=node(l,r,h2,-1);
            X[m]=l;
            X[m+1]=r;
        }
        m--;
        sort(nodes+1,nodes+1+m);
        sort(X+1,X+1+m);
        k=1;
        for(int i=2;i<=m;i++){
        	if(X[i]!=X[i-1]) X[++k]=X[i];
        }
        build(1,1,k-1);
        double ans=0;
        for(int i=1;i<m;i++){
            int l=binary_search(nodes[i].l);
            int r=binary_search(nodes[i].r)-1;
            if(l<=r) update(1,1,k-1,l,r,nodes[i].state);
            ans+=sgt[1].ss*(nodes[i+1].h-nodes[i].h);
        }
        printf("%.2f\n",ans);
    }
}
posted @ 2021-05-02 22:11  fxq1304  阅读(30)  评论(0编辑  收藏  举报