众所周知,这是一个十分暴力的算法,但是,他却站在了众多暴力算法的顶端,其看似简单实则十分玄妙的思想,牵扯出了一大串更加高端的算法。
进入正题
例题什么的不说了,因为分块的用法实在太广泛,为了不限制各位对分块美好的遐想,我还是直入主题吧。
分块可以用来维护一个序列。
对于这个长度为 nnn 的序列,我们能将他分成 n\sqrt nn 份,每份都含有 n\sqrt nn 个元素(因为 nnn 一般不是完全平方数,所以最后一块的元素数量可以少于 n\sqrt nn,问题不大),用一个belong数组记录下每一个元素属于哪一块,例如有一个含有 101010 个元素的序列,那么它的belong数组就是这样的:1,1,1,2,2,2,3,3,3,41,1,1,2,2,2,3,3,3,41,1,1,2,2,2,3,3,3,4,那么还需要一个 lll 数组,一个 rrr 数组,分别记录每一块的左边界和右边界。
那么对于这样一个十分灵活的东西,用处也是非常多,经典的衍生算法有分段打表,莫队等等。这里以一个朴素的区间修改区间查询为例。
对于每一次对区间[l,r][l,r][l,r]的操作,一般长这个样子:
中间的蓝色部分是几个整块连在一起,我们可以事先处理好每一块的答案,这里直接用即可。
两边的紫色部分也很容易搞,直接暴力过一遍求解即可。
这是查询。
修改也类似,两边暴力改,中间打个lazy标记即可。
分块的用途实在太多,有些仅仅是用到其思想,比如莫队算法,有些很巧妙的使用,比如分段打表。
那么什么时候使用分块算法呢?
分块算法有一个重要的限制,就是不同块的答案是可以快速合并的,满足了这一大要求,基本上就可以使用分块了。