zoukankan      html  css  js  c++  java
  • 扫描线学习笔记

    扫描线学习笔记

    前言

    之前翻阅网络上的讲解,可能是我太菜了,反正看了几次都没学会,也没敲过,于是这次就认真地学习了一下,发现并不是很难。

    引入

    给你 \(n\) 个矩形,求这 \(n\) 个矩形的面积并。保证所有的矩形

    \(n\leq 10^5,x,y\leq 10^9\)

    面积并:平面上所有图形的覆盖面积。

    对于这样一道问题,我们如何去求解呢?

    熟悉扫描线的同学可能一眼就看出来这就是一道扫描线的板子题,如果我们不去想用扫描线去求,我们怎么做呢?

    最暴力的办法就是开个二维数组进行染色,最后扫一遍统计答案。但是我们发现,仅仅 \(x,y\) 就有 \(10^9\) 那么大,就是对于一个矩形也吃不消。

    或许有人说用容斥,但是这有 \(10^5\) 个矩形,如果我们对这些进行容斥的话,想想就头大。

    于是我们的扫描线就登场了。

    定义

    扫描线,顾名思义,就是用一根线模拟扫描的过程。

    你想从哪里到哪里扫都行,你要你能写对。

    最常见的就是从左往右扫,其次是从下往上扫。

    加入我们有下面几个矩形:

    我们所要求的是这块的面积

    我们拿一根线去扫它。

    思想

    我们发现,扫描线与矩形相交的长度是一直在变动的,碰到一个矩形的左边可能会变长,碰到矩形的右边可能会变短。

    我们把每个位置的扫描线赋予一个值 \(cover\) ,表示有多少个矩形覆盖在这个位置上,显然,当我们碰到一个矩形的左边时,这个矩形覆盖的所有位置的 \(cover++\) ,碰到一个矩形的右边时,这个矩形覆盖的所有位置的 \(cover--\) 。将矩形覆盖的所有位置的 \(cover\) 进行改变,很明显是一个区间操作,区间修改,很明显,就是线段树。

    对于 \(y\) 轴,我们建立一个线段树来维护这个扫描线,每次碰到矩形的一条边,我们就对线段树进行操作。

    但是,

    我们发现 \(x,y\le 10^9\) 显然线段树开不了这么大。但我们发现,\(n\le 10^5\),一个矩形两条边,最多也就 \(2\cdot 10^5\) 个坐标。然后我们离散化就好了。

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/jcgf/p/15261349.html
Copyright © 2011-2022 走看看