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]])这条横边。可以看到,这里很机智地把右端点的对应关系给改了下,于是就兼容了

  • 相关阅读:
    h5页面页面在iphoneX手机上底部会有留白解决办法
    自定义单张图片放大预览功能,可支持手势缩放,依赖jquery
    js事件内部有click事件时,click事件会重复调用解决方法
    h5页面通过阿里云的broswer-js-sdk上传文件
    python字符串前加r、f、u、l 的区别
    Python基础面试题 :计算列表中出现最多次的字符
    python基础入门教程:传参是传值还是传引用
    Python 面试题:输入一个数组,输出该数组的第二大的数字
    Python 7种超实用的数据清洗方法,这你一定要掌握
    python教程:3个非常有用的内置函数(filter/map/reduce)
  • 原文地址:https://www.cnblogs.com/Arielzz/p/14213399.html
Copyright © 2011-2022 走看看