扫描线学习笔记
前言
之前翻阅网络上的讲解,可能是我太菜了,反正看了几次都没学会,也没敲过,于是这次就认真地学习了一下,发现并不是很难。
引入
给你 \(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\) 个坐标。然后我们离散化就好了。