zoukankan      html  css  js  c++  java
  • 扫描线

    一种求多个矩形和周长(∪)的方法

    扫描线:假设有一条扫描线从一个图形的下方扫向上方(或者左方扫到右方),那么通过分析扫描线被图形截得的线段就能获得所要的结果。该过程可以用线段树实现——洛谷题解

    面积并

    二话不说先上图——自己画图贼丑,所以暂且借一下洛谷的图

    如何求上面两个矩形的面积呢??

    我们假设一条扫描线从下方开始向上扫,扫到横边的时候停止、

    首先我们将矩形的上下边分为上位边(即y坐标大的那条平行于x轴的边),和下位边(y坐标小的平行于x轴的边).然后我们把所有矩形的上下位边按照他们y坐标从小到大排序,可以得到4条扫描线:

    根据图可以看出,对图形面积有贡献的是横边左右端点的坐标,我们把矩形的下边赋予权值为1,上边为-1,然后把所有的边按照纵坐标大小升序排序(模拟扫描过程);

    然后捏??

    线段树是个好东西(每次都挂

    我们把所有的边离散化,把横坐标存到一个数组里,升序排列,然后去重(防止x为浮点数且很大无法进行线段树)

    上图可以看出,四个横坐标把x轴分成了5段,我们取中间3段间线段树维护

    其中每个端点维护每个线段信息:

    1.该线段被覆盖了多少次(被多少个矩形所覆盖)
    2.该线段内被整个图形所截的长度是多少

    显然,只要一条线段被覆盖,那么它肯定被图形所截。所以,整个问题就转化为了一个区间查询问题,即:每次将 当前扫描线扫到的边 对应的信息 按照之前赋上的权值更新,然后再查询线段树根节点的信息,最后得到当前扫描线扫过的面积。这就可以用线段树来实现了

    模拟过程

    我们已经知道,这棵线段树的每个节点都对应了一条线段。考虑将线段树上节点对应的区间和横边建立映射关系。先看对于一个叶子节点(x),建树时保证了(tree[x].l=tree[x].r)但其保存的信息很显然不可能只是某条线段的一个端点(如果一条线段的两个端点重合,那么它实质上仅是一个点)。再看一个节点的左右儿子,同样地,建树的时候已经保证了左右儿子的区间不会重合(交集为空),但是看这样两条相邻线段:([1,2],[2,3])你会发现([1,2]∩[2,3]={2}),也就是说左儿子的右端点和右儿子的左端点其实是重合的。

    考虑把线段树每个节点(x)对应的区间((tree[x].l,tree[x].r))不变,改变区间和横边的映射关系,具体为:节点(x)对应([X[tree[x].l],X[tree[x].r+1]])这条横边。可以看到,这里很机智地把右端点的对应关系给改了下,于是就兼容了

  • 相关阅读:
    作业 20181204-1 每周例行报告
    对团队成员公开感谢
    附加作业 软件工程原则的应用实例分析
    作业 20181127-2 每周例行报告
    作业 20181120-1 每周例行报告
    作业 20181113-2 每周例行报告
    作业 20181030-4 每周例行报告
    作业 20181023-3 每周例行报告
    SDWebImage的实现原理与底层结构拆解
    计算文件或者文件夹的大小用于计算下载速度或者是显示清除缓存大小
  • 原文地址:https://www.cnblogs.com/Arielzz/p/14213399.html
Copyright © 2011-2022 走看看