分块这么名字, 听起来十分的高大上 并没有 , 但是实际 板子 理解起来不是很难.
对于一个需要维护某种区间上的信息的序列, 我们可以将其拆分为几个子区间, 也就是块 . 这样, 对于每一个块, 我们可以分别维护块中的某一个值, 在查询区间中的该值时, 只需要将区间落到块上, 进行求解, 就可以大大缩小复杂度.
相较于线段树( \(O(\log_2n)\) ), 分块本身的复杂度是比较高(\(O(\sqrt n)\))的.
但是, 分块( 相对线段树 )有如下优点:
在考试时, 分块也是一种得 骗 分的好办法.
以 P3372 线段树1 为例.
首先, 我们将整个范围分成若干一定大小的块.
然后我们对于每个块像线段树的区间一样进行预处理, 处理出每个块的总和.
接下来进行操作, 对于每次操作( 无论是修改还是查询 )的区间 \(\left[l,r\right]\) , 都有如下的几种情况:
\(l\), \(r\) 在同一个块中:
? 此时我们无法利用分块的性质, 但因为范围不大( 最大\(\sqrt n\) ), 所以我们可以放心的直接操作.
? 法同 1.
? 这时, 对于两边的块( \(l\), \(r\) 两端点所在的块 ), 我们仍然直接处理, 但是中间的完整的块, 我们就可以直接利用之前维护的值来更新了.
总复杂度: \(O(\sqrt n)\).
附:实际上, 分块是一个 "原序列 -- 块 -- 值" 三层的树形结构.
原文:https://www.cnblogs.com/Foggy-Forest/p/13267943.html