hdu1542 线段树+扫描线 计算矩形面积并

hdu1542 Atlantis
传送门

题意

\(n(1\leq n\leq 100)\)个矩形,每个矩形的左下角坐标为\((x_1,y_1)\),右上角坐标为\((x_2,y_2)\),其中\(0\leq x_1<x_2 \leq 100000, 0\leq y_1<y_2 \leq 100000\),坐标为实数,计算所有矩形面积并。

题解

线段树+扫描线

从下向上扫描,每个矩形分为上位边和下位边,拥有的信息为:
l:左端点\(x\)坐标
r:右端点\(x\)坐标
h:\(y\)坐标
d:上位边还是下位边

线段树中维护两个变量:
\(cnt\):当前节点维护的区间被覆盖的次数,\(cnt=-1\)表示当前节点的左儿子和右儿子的\(cnt\)不一致
\(sum\):当前节点维护的区间中\(cnt\)不为\(0\)的实际区间的总长度

\(x\)坐标离散化,线段树维护,离散化数组为\(X\),线段树中的节点\(l\)表示\([X[l],X[l+1]]\)这段区间被覆盖的次数

#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=110;
int n,cas,k;
double X[2*maxn];

struct node{
    double l,r,h;// l表示x左端点,r表示x右端点,h表示y坐标
    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 sum;
}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 pushup(int o){
    if(sgt[o<<1].cnt==-1 || sgt[o<<1|1].cnt==-1){
        sgt[o].cnt=-1;
    }
    else if(sgt[o<<1].cnt!=sgt[o<<1|1].cnt){
        sgt[o].cnt=-1;
    }
    else{
        sgt[o].cnt=sgt[o<<1].cnt;
    }
    sgt[o].sum=sgt[o<<1].sum+sgt[o<<1|1].sum;
}

void pushdown(int o,int l,int r){
    int mid=(l+r)>>1;
    if(sgt[o].cnt!=-1){
        sgt[o<<1].cnt=sgt[o<<1|1].cnt=sgt[o].cnt;
        sgt[o<<1].sum=(sgt[o<<1].cnt?X[mid+1]-X[l]:0);
        sgt[o<<1|1].sum=(sgt[o<<1|1].cnt?X[r+1]-X[mid+1]:0);
    }
}

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

void update(int o,int l,int r,int ql,int qr,int state){
    if(ql<=l && r<=qr){
        if(sgt[o].cnt!=-1){
            sgt[o].cnt+=state;
            sgt[o].sum=(sgt[o].cnt?X[r+1]-X[l]:0);
            return;
        }
    }
    pushdown(o,l,r);
    int mid=(l+r)>>1;
    if(ql<=mid) update(lson,ql,qr,state);
    if(qr>mid) update(rson,ql,qr,state);
    pushup(o);
}

int main(){
   while(scanf("%d",&n)!=EOF && n){
       printf("Test case #%d\n",++cas);
       int m=0;
       for(int i=1;i<=n;i++){
           double l,r,h1,h2;
           scanf("%lf %lf %lf %lf",&l,&h1,&r,&h2);
           nodes[++m]=node(l,r,h1,1);
           X[m]=l;
           nodes[++m]=node(l,r,h2,-1);
           X[m]=r;
       }
       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];
       }
       sort(nodes+1,nodes+1+m);
       build(1,1,k-1);
       double ans=0.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].sum*(nodes[i+1].h-nodes[i].h);
       }
       printf("Total explored area: %.2f\n\n",ans);
   }
}
posted @ 2020-11-19 23:41  fxq1304  阅读(3)  评论(0)    收藏  举报