浅谈扫描线

前言

之前在qbxt听lxl讲课的时候,一直在强调扫描线很重要,知道学了之后才明白这东西好用归好用,难写归难写。

预备知识

线段树,平衡树,各种数据结构,离线询问……

概念

因为有很多题我们难以直接分析出性质,再加之人类本身就有几何直观性,因此,扫描线就诞生了。

再说说扫描线,就是将问题中一些关键点放到平面上的一种思路。

其实扫描线的本质就是将静态的二维问题变成动态的一维问题。

还是放在例题里将比较明白吧……

不算例题的例题

二维数点,可以在 \(O(n log n)\) 内解决

考虑构建平面,将点放在上面。

然后将每个询问看做在平面上的矩形查询,那么就会如图:

IrbMEn.png

但是发现好像不太好做一个 \(4-side\) 矩形的查询

那就差分,把一个 \(4-side\) 矩形差分成4个 \(2-side\) 矩形,就很好处理了。

和上面的数据不一样,但是还是看看图吧

Irb04x.png

然后想有一根线从左扫到右边,那根线是一个什么随便一个数据结构,每遇到一个点就单点加,遇到一条边就区间查,最后合并答案,就算完了。

差不多图长这样:

Irbo28.png

不算例题的例题+1

求每个点被多少个给定的\(n\)个矩形包含,可以在 \(O(n log n)\) 内解决

大概就是这样,考虑使用扫描线,将每个矩形的左边界和右边界分开处理,左边区间加,右边区间减,遇见点的时候单点查询。

例题1

P1972 [SDOI2009]HH的项链

简化版题意:静态的区间数颜色

看到这道题,我们不难想到一个莫队解法,但是与本题没什么关系,现在可能也过不去了。

首先,我们不难得出一个性质:区间内如果一个颜色是第一次出现,那么他上一次出现必然在区间外。

这个看起来很显然的性质能够有大用。

这个时候,我们发现每一个元素有两维,一个是位置,一个是前驱的位置。

将他们放到平面上,就转化成了一个二维数点问题,也可以仿照上面的那个东西,把\(3-side\)矩形差分成2个\(2-side\)矩形,之后可以拿扫描线解决,具体看下图。

数据:

4 6 5 2 5 1 2 5 1 7
6 10
7 9
1 5
4 7
3 8

IrLZwj.png

code

例题2

经典问题:矩形面积并

P5490 【模板】扫描线

离散化什么的都是小问题,先不考虑那些有的没的,就假设离散化完了或者不用离散化。

考虑把这种矩形并给分开来算,就是分割矩形,大体来说,就是用扫描线扫横坐标,数据结构维护纵坐标。

分割之后:

接下来问题来了,怎么用数据结构维护纵坐标呢?

还是相似地考虑,走到矩形左边时区间加,右边时区间减,那维护答案时就是 全局非零值的个数 \(\times\) 两根线的宽度

如何维护全局非零个数?

使用线段树,对于每一个节点,我们维护最小值和最小值个数,在合并时,如果最小值不同,取较小值,然后继承较小值那边的个数;如果最小值相等,那么就直接把个数相加

在最后,我们检验最小值是否是零就可以维护了qwq

例题3

BZOJ 4212

给定许多模式字符串,然后查询时每次给你两个字符串s1,s2,问你这一堆模式串里有多少个串满足前缀是s1,后缀是s2的

来一个 \(O(\left| S \right| + (m+n)logn)\) 的做法

见到了前缀,后缀,字符串,不妨考虑一下我们可爱的 \(trie\)

我们建两棵 \(trie\) 树,一棵叫 \(T1\) ,用来正着插入那一堆模式串,还有一棵叫 \(T2\) ,用来倒着插入那一堆模式串

之后我们不难发现,如果对于一个模式串 \(S1\) ,它的前缀可以在 \(T1\) 里面找,后缀可以在 \(T2\) 里面找。

那么对于询问时给出的那两个字符串,如果前一个在 \(T1\) 中匹配到的地方dfs序是 \(l1,r1\) ,后一个在 \(T2\) 中匹配到的地方dfs序是 \(l2,r2\),那么就有一个结论

满足题目条件的字符串的首字符的dfs序和末尾字符的dfs序必然在 \(l1,r1\)\(l2,r2\)

那么考虑把他们放到平面上,每一个字符串代表的点的横坐标就是他在 \(T1\) 中的dfs序,纵坐标就是他在 \(T2\) 中的dfs序

每一次询问都是一个二维数点了qwq

例题4

BZOJ 3489弱化版

题意很简单,现就不考虑强制在线的版本,我也不会说的……

我们不妨换个角度去说这个东西,不去考虑询问时怎么办,而是考虑每个元素会对可能的答案产生什么贡献

那么这个时候,我们就想一想元素怎么出现,区间怎么分布,可能会产生贡献

如下图

\(a,b,c,d\) 处都出现了 \(x\) 那么可以发现,只有绿框的情况下会产生贡献,红框是不行的

那么绿框的范围是相邻的两个区间,也就是左端点在一个区间,右端点在一个区间

同时,绿框的数量是 \(n\)

把它放到二维平面内,就变成了 \(n\) 次矩形加, \(m\) 次单点查,形同点矩形包含

posted @ 2021-11-10 21:29  sky_light  阅读(313)  评论(0)    收藏  举报