zoukankan      html  css  js  c++  java
  • HDU1255覆盖的面积

    Bryce1010模板

    http://acm.hdu.edu.cn/showproblem.php?pid=1255
    线段树模板:矩形面积并

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m,r,rt<<1|1
    const int MAXN=1e5+10;
    
    double y[MAXN<<2];
    struct Line
    {
        double x;//记录线段位置
        double y_up,y_down;
        int flag;//左线段为1,右线段为-1
    }line[MAXN<<2];
    
    struct Node
    {
        double l,r,x;//l维护区间,r维护右区间,x记录上一个x的位置,用于求面积
        bool flag;//标记只有一个区间的节点,将连续的区间离散化为节点
        int cover;//记录覆盖的线段数
    
    
    }tree[MAXN<<2];
    
    void pushup(int rt)
    {
        tree[rt].l=tree[rt>>1].l;
        tree[rt].r=tree[rt>>1|1].r;
    }
    
    void build(int l,int r,int rt)
    {
        tree[rt].l=y[l];
        tree[rt].r=y[r];
        tree[rt].x=-1;//前一个位置
        tree[rt].flag=false;//不是只有一个区间
        tree[rt].cover=0;
        if(l+1==r)//因为是区间是连续数
        {
            tree[rt].flag=true;//叶子节点
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);//区间是连续的,m不需要+1
    }
    //flag表示左边线段还是右边线段,碰到左边线段+1,碰到右边线段-1
    double query(double l,double r,int rt,double x,int flag)
    {
        //如果查找区间不在范围内
        if(l>=tree[rt].r||r<=tree[rt].l)
        {
            return 0;
        }
        //如果是只有一个区间的节点,叶子节点
        if(tree[rt].flag)
        {
            //观察当前范围是否有覆盖区间
            if(tree[rt].cover>1)
            {
                //计算面积
                double pre=tree[rt].x;
                double ans=(x-pre)*(tree[rt].r-tree[rt].l);
                tree[rt].x=x;//更新这个节点,方便下一次计算
                tree[rt].cover+=flag;
                return ans;
            }
            else
            {
                tree[rt].x=x;
                tree[rt].cover+=flag;
                return 0;
            }
        }
        double ans1,ans2;
        ans1=query(l,r,rt<<1,x,flag);
        ans2=query(l,r,rt<<1|1,x,flag);
        return ans1+ans2;
    }
    
    bool cmp(Line l1,Line l2)
    {
        return l1.x<l2.x;
    }
    
    int main()
    {
        int t,n;
        double x1,y1,x2,y2;
        cin>>t;
        while(t--)
        {
            cin>>n;
            int cnt=-1;
            for(int i=0;i<n;i++)
            {
                cin>>x1>>y1>>x2>>y2;
                y[++cnt]=y1;
                line[cnt].x=x1;
                line[cnt].y_down=y1;
                line[cnt].y_up=y2;
                line[cnt].flag=1;
    
    
                y[++cnt]=y2;
                line[cnt].x=x2;
                line[cnt].y_down=y1;
                line[cnt].y_up=y2;
                line[cnt].flag=-1;
            }
            //将所有高度排序
            sort(y,y+cnt+1);
            //将所有线段排序
            sort(line,line+cnt+1,cmp);
            build(0,cnt,1);
            //扫描线扫描所有的线段
            double area=0;
            for(int i=0;i<=cnt;i++)
            {
                area+=query(line[i].y_down,line[i].y_up,1,line[i].x,line[i].flag);
            }
    
            printf("%.2f
    ",area);
    
        }
    
    
        return 0;
    }
    
  • 相关阅读:
    1.python的Helloword
    java实现多个属性排序---按照实体的多种属性值进行排序(ComparableComparator/ComparatorChain)
    Spring Boot 2.X(一):入门篇
    Nginx开启Gzip压缩提升页面加载速度
    QQ第三方授权登录OAuth2.0实现(Java)
    Windows下IIS搭建Ftp服务器
    【Java】支付宝获取人脸采集认证的图片base64格式
    【SpingBoot】spring静态工具类注入问题
    【linux】Tomcat 安装
    【linux】jdk安装及环境变量配置
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9386854.html
Copyright © 2011-2022 走看看