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


    hdu1255 覆盖的面积
    传送门

    题意

    平面上给出(n(1leq nleq 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
    ",ans);
        }
    }
    
  • 相关阅读:
    【数据操作】存储过程编写经验和优化措施
    【项目管理】产品经理的核心能力模型(译)
    [转] SAP DEVELOPMENT TECHNOLOGY LIST
    【架构设计】五个基本工作流模式(转)
    【工具推荐】Office Open XML
    【经验分享】企业可选的当前主流OA产品
    【项目管理】项目启动阶段 制定项目章程
    【转贴文章】 Dos命令收集
    【架构设计】Web应用程序安全性简介
    [转]what is SAP NetWeaver
  • 原文地址:https://www.cnblogs.com/fxq1304/p/14726644.html
Copyright © 2020-2023  润新知