zoukankan      html  css  js  c++  java
  • 扫描线+线段树例题(HDU1542)

    主要作为代码参考

    http://acm.hdu.edu.cn/showproblem.php?pid=1542


    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    const int M=2222;
    double X[M];//离散化
    struct node{
        double l,r,h;//因为有小数,所以我们存边的时候要存为小数
        int d;//存上边还是下边
    }nodes[M];
    struct t{//线段树 
        int cnt;//线段树存下边数-上边数,如果子节点下边数-上边数不同我们直接赋值-1
        double sum;//区间长度
    }tr[M*4];
    bool cmp(node a,node b){
        return a.h<b.h;
    }
    void pushup(int i){//上推 
        if(tr[i*2].cnt==-1||tr[i*2+1].cnt==-1){
            tr[i].cnt=-1;
        }else if (tr[i*2].cnt!=tr[i*2+1].cnt){
            tr[i].cnt=-1;
        }else
            tr[i].cnt=tr[i*2].cnt;
        tr[i].sum=tr[i*2].sum+tr[i*2+1].sum;
    }
    void pushdown(int i,int l,int r){
        int mid=(r+l)/2;
        if(tr[i].cnt!=-1){
            tr[i*2].cnt=tr[i*2+1].cnt=tr[i].cnt;
            if(tr[i].cnt==0){
                tr[i*2].sum=tr[i*2+1].sum=0;
            }else{
                tr[i*2].sum=X[mid+1]-X[l];
                tr[i*2+1].sum=X[r+1]-X[mid+1];
            }
        }
    }
    void build(int i,int l,int r){//建线段树 
        if(l==r){//叶子结点 
            tr[i].sum=0;
            tr[i].cnt=0;
            return;
        }
        int mid =(r+l)/2;
        build(i*2,l,mid);
        build(i*2+1,mid+1,r);
        pushup(i);
    }
    void update(int i,int l,int r,int x,int y,int d){
        if(x<=l&&y>=r){
            if(tr[i].cnt!=-1){
                tr[i].cnt+=d;
                tr[i].sum=(tr[i].cnt?(X[r+1]-X[l]):0);
                return;
            }
        }
        pushdown(i,l,r);
        int mid=(r+l)/2;
        if(x<=mid)
        update(i*2,l,mid,x,y,d);
        if(y>mid)
        update(i*2+1,mid+1,r,x,y,d);
        pushup(i);
    }
    int bin(double k,int n,double d[]){
        int l=1,r=n;
        while(l<=r){
            int mid=(r+l)/2;
            if(d[mid]<k){
                l=mid+1;
            }else if(d[mid]==k)
            	return mid;
            else{
                r=mid-1;
            }
        }
        return -1;
    }
    int main(){
        int q;
        int kase=0;
        while(~scanf("%d",&q)&&q){
            int n=0,m=0;
            for(int i=1;i<=q;i++){
                double x1,y1,x2,y2;
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                X[++n]=x1;//存边 
                nodes[++m].l=x1;
                nodes[m].r=x2;
                nodes[m].h=y1;
                nodes[m].d=1;
                X[++n]=x2;
                nodes[++m].l=x1;
                nodes[m].r=x2;
                nodes[m].h=y2;
                nodes[m].d=-1;
            }
            sort(X+1,X+1+n);
            sort(nodes+1,nodes+1+m,cmp);//排序 
            int k=1;
            for(int i=2;i<=n;i++){
                if(X[i-1]!=X[i])
                    X[++k]=X[i];//离散化 
            }
            build(1,1,k-1);//在x轴上一共有k-1段
            double ret=0.0;
            for(int i=1;i<m;i++){
                int x,y;
                x=bin(nodes[i].l,k,X);
                y=bin(nodes[i].r,k,X)-1;
                if(x<=y)
                update(1,1,k-1,x,y,nodes[i].d);
                ret+=tr[1].sum*(nodes[i+1].h-nodes[i].h);
            }
            printf("Test case #%d
    Total explored area: %.2lf
    
    ",++kase,ret);
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 1110. Delete Nodes And Return Forest
    LeetCode 473. Matchsticks to Square
    LeetCode 886. Possible Bipartition
    LeetCode 737. Sentence Similarity II
    LeetCode 734. Sentence Similarity
    LeetCode 491. Increasing Subsequences
    LeetCode 1020. Number of Enclaves
    LeetCode 531. Lonely Pixel I
    LeetCode 1091. Shortest Path in Binary Matrix
    LeetCode 590. N-ary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680640.html
Copyright © 2011-2022 走看看