二维分块浅谈
sSkYy · · Algo. & Theory
我们以例题探究二维分块的运用以及对分块复杂度的分析,学习如何有效分块
题目大意
给定
试求存在奇环的连通块上的所有点、
数据范围
发现边数最多有
复杂度
subtask3:r\leq 10
由于r很小,考虑用 map 将所有点按坐标归类
这样我们可以把染色时把枚举所有点换成只枚举距离该点
复杂度
subtask4:任意两点间距离不小于 \frac{r}{2}
这是很关键的一个 subtask。
点之间距离足够大保证了边数是线性的,可以说边数与点数成正比,边数不多。
可以建图,关键在于如何找出这些边。
这里分块第一是为了方便确定可能连边的范围,第二是为了利用
将平面划分为边长为
对于每个点,考虑所有落在距离它所在格子在
由于每个格子上至多只有 2 个点,所以连边建图的复杂度为
这是至关重要的一点,只有分块了我们才能以格子为单位快速枚举而不用一个一个坐标枚举,就像分块链表一样可以以格子为单位加快跳转,这是有效的分块。
整体时间复杂度
subtask5:y_i=0
只有一维,具有更多的单调性,不难想到,除了连边除了相邻的点还有跳着连的,跳着连的会形成环。
那么显然如果从一个点开始能够跳过 3 个点,5 个点形成奇环,那么肯定可以跳过 1 个点形成长度为 3 的最小奇环。
所以贪心地只用判断是否存在长度为 3 的奇环即可,这样子就节省了许多不必要的连边。
复杂度
正解
正解需要充分结合上述 subtask 的思路,最重要的是分块复杂度的分析。
问题的关键就在于减少不必要的连边,这里同样要用到分块的思想。
还是按照 subtask4 的方法分块,不同的是块内可能不止 2 个点了。
我们将点数
对于重块,不难发现在同一个块内一定可达,所以重块内一定存在奇环,也就是说重块内的点一定是满足要求的点,因此重块之间可以不需要连边,因为连不连都满足要求。
对于轻块,像先前一样向
也就是说重块上的点至多与
于是乎,复杂度神一般的降到了
最重要的原因是,这种方法免去了重块之间的连边,使得大部分点集中的区域都不需要连边,极大的减少了边数,是有效的。
最难想到的还是复杂度分析,只有你确信这是
具体实现的话,先分块,再枚举每个块。
对于重块,只需直接将块上的点记录答案。
对于轻块,像 subtask4 一样连边。
最后跑一边黑白染色即可。
总结
有些题目在 subtask 中就暗藏题眼,这个题目最重要的线索是 为什么是