zoukankan      html  css  js  c++  java
  • O

    分析:求一层的面积覆盖是非常简单的事情,不过多层面积覆盖应该怎么搞???也是比较简单的事情,只需要用两个变量记录就好了,一个记录覆盖一次的,一个记录覆盖两次的,就很容易解决了

    ************************************************************************
    #include<stdio.h>
    #include<algorithm>
    #include<math.h>
    using namespace std;

    #define Lson r<<1
    #define Rson r<<1|1

    const int MAXN = 1e5+5;

    struct segmentTree
    {///cover 记录区间被覆盖了多少次
        int L, R, cover;
        double len1, len2;///分别记录被覆盖一次和多次时候的长度
        int mid(){return (L+R)>>1;}
    }a[MAXN<<2];
    ///保存离散化后的数据,nh是数组大小
    double Hash[MAXN]; int nh;

    ///dir等于 1 是y的左边, -1是y的右边
    struct Point{double x, y1, y2; int dir;}ege[MAXN];
    bool cmp(Point n1, Point n2)
    {///按照x从小到大排序
        return n1.x < n2.x;
    }
    double FindSegLen(int y1, int y2)
    {///查找线段的长度, y1 < y2
        return Hash[y2] - Hash[y1];
    }
    void BuildTree(int r, int L, int R)
    {
        a[r].L = L, a[r].R = R, a[r].cover = 0;
        a[r].len1 = a[r].len2 = 0;

        if(L == R-1)return ;

        BuildTree(Lson, L, a[r].mid());
        BuildTree(Rson, a[r].mid(), R);
    }
    void PushUp(int r)
    {
        if(a[r].cover > 1)
            a[r].len1 = a[r].len2 = FindSegLen(a[r].L, a[r].R);
        else if(a[r].L == a[r].R-1 && a[r].cover == 1)
            a[r].len1 = FindSegLen(a[r].L, a[r].R), a[r].len2 = 0;
        else if(a[r].L == a[r].R-1)
            a[r].len1 = a[r].len2 = 0;
        else if(a[r].cover == 1)
        {///不是叶子节点点,覆盖两次以上的就等于子树覆盖一次的
            a[r].len2 = a[Lson].len1 + a[Rson].len1;
            a[r].len1 = FindSegLen(a[r].L, a[r].R);
        }
        else
        {///区间未被覆盖过,只能等于子树被覆盖的情况
            a[r].len1 = a[Lson].len1 + a[Rson].len1;
            a[r].len2 = a[Lson].len2 + a[Rson].len2;
        }
    }
    void UpData(int r, int L, int R, int dir)
    {///注意叶子节点的合并操作
        if(a[r].L == L && a[r].R == R)
        {
            a[r].cover += dir;
            PushUp(r);

            return ;
        }

        if(R <= a[r].mid())
            UpData(Lson, L, R, dir);
        else if(L >= a[r].mid())
            UpData(Rson, L, R, dir);
        else
        {
            UpData(Lson, L, a[r].mid(), dir);
            UpData(Rson, a[r].mid(), R, dir);
        }

        PushUp(r);
    }

    int main()
    {
        int i, T, N;

        scanf("%d", &T);

        while(T--)
        {
            double x1, x2, y1, y2, area=0int k=0; nh = 0;

            scanf("%d", &N);

            for(i=0; i<N; i++)
            {
                scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
                ege[k].x=x1, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=1;///左边
                ege[k].x=x2, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=-1;///右边
                Hash[nh++] = y1, Hash[nh++] = y2;
            }

            sort(Hash, Hash+nh);///排序并且去重复
            nh = unique(Hash, Hash+nh) - Hash;

            ///建立以1区间为单位的线段树
            BuildTree(10, nh-1);

            ///对y边按照x从小到大排序
            sort(ege, ege+k, cmp);

            for(int i=0; i<k-1; i++)
            {
                int L = lower_bound(Hash, Hash+nh, ege[i].y1)-Hash;
                int R = lower_bound(Hash, Hash+nh, ege[i].y2)-Hash;

                UpData(1, L, R, ege[i].dir);;

                area += a[1].len2 * (ege[i+1].x - ege[i].x);
            }

            printf("%.2f ", area);
        }

        return 0;
    }
  • 相关阅读:
    jchdl
    jchdl进展
    Verilog缺少一个复合数据类型,如C语言中的结构体
    jchdl-GSL-实例
    硬件建模-几个观点
    非阻塞赋值(Non-blocking Assignment)是个伪需求
    jchdl
    jchdl
    HDU 2686 (双线程) Matrix
    LA 3602 DNA Consensus String
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4686127.html
Copyright © 2011-2022 走看看