• HDU 1542:线段树


    题意:给N个矩形,会相互重叠,重叠部分只算一次面积,求总面积

    把X坐标排序后离散化成0~m标号,每个标号代表一个点及其和下一个点之间的长度,所以m个点有m-1段。按0~m-1标号建线段树

    上边赋值为-1,下边赋值为1,这样一段长度非零的时候,说明当前该段长度是被覆盖的,还需要被计算

    这里比较难维护的就是区间的有效长度len

    比如说有一个结点,范围是0~2,它的标记值是0,不是代表0~2这段都未被覆盖,而是代表0~2未被整体覆盖,所以其下的点0、1、2当前仍可能被覆盖着

    为了解决这个问题,我们每次更新一个区间的len值后马上pushup,这样就可以保证区间len一直是正确的。

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"map"
    #include"set"
    #include"vector"
    #define ll long long
    #define mems(a,b) memset(a,b,sizeof(a))
    #define ls pos<<1
    #define rs pos<<1|1
    
    using namespace std;
    const int MAXN = 100500;
    const int MAXE = 1005;
    const int INF = 0x3f3f3f3f;
    
    struct Node{
        int l,r;
        double len;
        int w;
    }node[MAXN<<2];
    
    struct seg{
        double l,r,h;
        int w;
        seg(){}
        seg(double a,double b,double c,int d):l(a),r(b),h(c),w(d){}
    }line[MAXN<<1];
    double h[MAXN<<1];
    int n,m,p=1;
    
    bool cmp(seg a,seg b){
        return a.h<b.h;
    }
    
    int get_pos(double x){
        int low=0,high=m,mid;
        while(low<=high){
            mid=(low+high)>>1;
            if(h[mid]==x) return mid;
            else if(h[mid]>x) high=mid-1;
            else low=mid+1;
        }
    }
    
    void pushup(int pos){
        if(node[pos].w) node[pos].len=h[node[pos].r+1]-h[node[pos].l];
        else if(node[pos].l==node[pos].r) node[pos].len=0;
        else node[pos].len=node[ls].len+node[rs].len;
    }
    
    void build(int l,int r,int pos){
        node[pos].l=l;
        node[pos].r=r;
        node[pos].len=0;
        node[pos].w=0;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(l,mid,ls);
        build(mid+1,r,rs);
    }
    
    void update(int l,int r,int pos,int w){
        if(l<=node[pos].l&&node[pos].r<=r){
            node[pos].w+=w;
            pushup(pos);            ///这里是关键- -
            return ;
        }
        int mid=(node[pos].l+node[pos].r)>>1;
        if(l<=mid) update(l,r,ls,w);
        if(r>mid) update(l,r,rs,w);
        pushup(pos);
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        while(scanf("%d",&n)&&n){
            printf("Test case #%d
    ",p++);
            for(int i=0;i<2*n;i+=2){
                double x1,x2,y1,y2;
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                line[i]=seg(x1,x2,y1,1);
                line[i+1]=seg(x1,x2,y2,-1);
                h[i]=x1;
                h[i+1]=x2;
            }
            sort(h,h+2*n);
            sort(line,line+2*n,cmp);
            m=0;
            for(int i=1;i<2*n;i++) if(h[i]!=h[i-1]) h[++m]=h[i]; ///去重
            double ans=0;
            build(0,m-1,1);
            for(int i=0;i<2*n-1;i++){
                int l=get_pos(line[i].l);
                int r=get_pos(line[i].r)-1;
    
                update(l,r,1,line[i].w);
                ans+=(line[i+1].h-line[i].h)*node[1].len;
            }
            printf("Total explored area: %.2lf
    
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    cenos安装memcache
    微信开发——测试号申请,接口配置,JS接口安全域名,自定义菜单
    mysql设计-优化
    mysql设计-基本操作
    CI框架部署后访问出现404
    ueditor的bug
    git操作
    github基本操作
    基于SSH协议clone GitHub远端仓库到本地-git
    Thinkphp5.0 路由
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5143376.html
Copyright © 2020-2023  润新知