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

************************************************************************
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std; #define Lson r<<1
#define Rson r<<1|1 const int MAXN = 1e5+; struct segmentTree
{///cover 记录区间被覆盖了多少次
    int L, R, cover;
    double len1, len2;///分别记录被覆盖一次和多次时候的长度
    int mid(){return (L+R)>>;}
}a[MAXN<<];
///保存离散化后的数据,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 = ;
    a[r].len1 = a[r].len2 = ;     if(L == R-)return ;     BuildTree(Lson, L, a[r].mid());
    BuildTree(Rson, a[r].mid(), R);
}
void PushUp(int r)
{
    if(a[r].cover > )
        a[r].len1 = a[r].len2 = FindSegLen(a[r].L, a[r].R);
    else if(a[r].L == a[r].R- && a[r].cover == )
        a[r].len1 = FindSegLen(a[r].L, a[r].R), a[r].len2 = ;
    else if(a[r].L == a[r].R-)
        a[r].len1 = a[r].len2 = ;
    else if(a[r].cover == )
    {///不是叶子节点点,覆盖两次以上的就等于子树覆盖一次的
        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=; int k=; nh = ;         scanf("%d", &N);         for(i=; 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=;///左边
            ege[k].x=x2, ege[k].y1=y1, ege[k].y2=y2, ege[k++].dir=-;///右边
            Hash[nh++] = y1, Hash[nh++] = y2;
        }         sort(Hash, Hash+nh);///排序并且去重复
        nh = unique(Hash, Hash+nh) - Hash;         ///建立以1区间为单位的线段树
        BuildTree(, , nh-);         ///对y边按照x从小到大排序
        sort(ege, ege+k, cmp);         for(int i=; i<k-; i++)
        {
            int L = lower_bound(Hash, Hash+nh, ege[i].y1)-Hash;
            int R = lower_bound(Hash, Hash+nh, ege[i].y2)-Hash;             UpData(, L, R, ege[i].dir);;             area += a[].len2 * (ege[i+].x - ege[i].x);
        }         printf("%.2f\n", area);
    }     return ;
}

O - 覆盖的面积 - hdu 1255(求面积)的更多相关文章

  1. 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))

    扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...

  2. 覆盖的面积 HDU - 1255(扫描线求面积交)

    题意: 就是扫描线求面积交 解析: 参考求面积并.... 就是把down的判断条件改了一下..由w > 0 改为 w > 1 同时要讨论一下 == 1 时  的情况, 所以就要用到一个临时 ...

  3. 覆盖的面积 HDU - 1255 (扫描线, 面积交)

    求n个矩阵面积相交的部分,和求面积并一样,不过这里需要开两个数组保存覆盖一次和覆盖两次以上的次数的部分,还是模板,主要注意点就是pushup部分,如果我已经被两次覆盖,那我的两个数组在这个root点的 ...

  4. 面积并+扫描线 覆盖的面积 HDU - 1255

    题目链接:https://cn.vjudge.net/problem/HDU-1255 题目大意:中文题目 具体思路:和上一篇的博客思路差不多,上一个题求的是面积,然后我们这个地方求的是啊覆盖两次及两 ...

  5. 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积

    #include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...

  6. 覆盖的面积(HDU 1255 线段树)

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem D ...

  7. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

  8. 扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]

    学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...

  9. hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)

    了校赛,还有什么途径可以申请加入ACM校队?  覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

随机推荐

  1. lamp安装指南(转)

    主要软件包, 1. httpd-2.2.6.tar.gz 2. mysql-5.0.45-linux-i686-glibc23.tar.gz ( 这个版本是已编译好的压缩包,解压后稍做配置即可使用 ) ...

  2. Java基础知识强化72:正则表达式之判断功能(手机号码判断 和 校验邮箱)

    1.  判断功能: 使用了String类的matches方法,如下: public boolean matches(String regex): 2. 判断手机号码的案例: package cn.it ...

  3. nginx 3.nginx+fastcgi

    死磕nginx 3.nginx+fastcgi 互联网服务器有个非常典型的架构lamp(linux+apache+mysql+php),由于其开源和强大的兼容性而风靡一时,不过随着nginx的横空出世 ...

  4. [HAOI2006]聪明的猴子

    /* 找出能连通所有点的一棵树 是的最大的边最小 很显然就是最小生成树. 堆优化prim. */ #include<iostream> #include<cstring> #i ...

  5. ASP.NET-FineUI开发实践-8(二)

    把上回的做一些改进 1.点击grid2的行改变TriggerBox1的值 var v = $(item).find('.x-grid-cell-Name div.x-grid-cell-inner') ...

  6. RecycleView 滑动到底部,加载更多

    android.support.v7 包提供了一个新的组件:RecycleView,用以提供一个灵活的列表试图.显示大型数据集,它支持局部刷新.显示动画等功能,可以用来取代ListView与GridV ...

  7. oracle 复制一条记录只改变主键不写全部列名

    场景:表TEST中有C1,C2,C3...字段,其中C1为主键,先需要复制表TEST中一条(C1='1'的)记录,修改主键列C1和需要变更的列后,再插入到表TEST中. procedure P_TES ...

  8. SQL 无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问。)"

    用T-SQL命令附加数据库时,出现如下异常信息: 无法打开物理文件 XXX.mdf".操作系统错误 5:"5(拒绝访问.)". (Microsoft SQL Server ...

  9. oracle 分布式数据库

    分布式数据库的数据库链路是单向的

  10. Caused by: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "mil_id")

    今天在使用mybatis处理数据库的时候,突然抛出了上述异常,让我感到很惊讶,因为在处理save的时候,在Mybatis的配置文件中,我根本就没有使用到ognl表达式,系统怎么会抛出上述异常.而且之前 ...