
算法学习笔记 -- 数列分块

数列分块基本思想
分块的基本思想就是, 把区间划分为若干连续的大块, 把区间操作按照大块和小块(散块)作不同处理, 从而取得比直接暴力更优的复杂度.
比如, 有两种操作, 区间加法(对区间
如果是朴素的暴力 (遍历加, 遍历求和), 那么单次操作复杂度是
如果我们提前把区间
思想很简单, 实现也不困难.
数列分块代码框架
分块的基本代码框架如下:
|
入门题集
以下是比较裸的入门题.
1. 数列分块入门 1 [区间加法, 单点查询]
AC Code
|
2. 数列分块入门 4 [区间加法, 区间求和]
AC Code
|
3. 数列分块入门7 [区间加法, 区间乘法, 区间求和]
Hint
这题需要注意的就是加法标记和乘法标记的优先级, 以及在暴力修改散块前, 需要先下放标记.
AC Code
|
4. 数列分块入门8 [区间赋值, 值查询]
Hint
用一个赋值标记维护大块的值, 如果是散块或者未标记的大块, 就暴力查询.
AC Code
|
5. 数列分块入门5 [区间开方, 区间求和]
Hint
假设
因此, 我们只需要维护大块的区间最大值, 每次只暴力做有意义的开方即可. 时间复杂度大概是
AC Code
|
6. 数列分块入门2 [区间加法, 小于 的元素个数]
Hint
这题和前面的题略有不同, 为了快速求出小于
AC Code
|
7. 教主的魔法 [区间加法, 大于等于 的个数]
Hint
和上一题没有本质不同.
AC Code
|
8. 数列分块入门3 [区间加法, 查询前驱]
Hint
这题和前两题几乎一样, 都是要维护一个大块的加法标记和有序序列.
AC Code
|
9. 数列分块入门9 [无修改, 查询区间最小众数]
Hint
这题应该是莫队板子, 但我还不会莫队, 依旧使用分块的在线做法.
首先, 对于众数, 我们并不关心具体数值, 只关心每个数的出现次数, 因此我们可以先做一个离散化, 把序列映射到
注意到题目的内存限制给到了
接下来考虑如何查询区间最小众数.
对于小区间 (区间在某个大块上), 我们直接暴力统计就行, 无伤大雅.
对于大区间, 显然, 整个大区间的众数, 只可能是某个大块的众数, 或者两个散块中的某个数.
全部大块的编号范围是 [id[l]+1, id[r]-1], 利用前面的预处理结果, 我们马上能得到全部大块的众数
然后, 再加上
然后, 再考虑散块中的数的频数, 和前面的
我的实现可能不太优雅, 仅供参考.
AC Code
|
10. [Violet] 蒲公英 [无修区间众数, 强制在线]
Hint
双倍经验.
AC Code
|
11. ycz的妹子
Hint
题意理解有一定难度.
初始建块的时候, 要注意
用一个has
维护第cnt
维护第
查找第cnt$
查, 没必要再维护 cnt
前缀和之类的.
其它没啥好说的, 看代码就行.
AC Code
|
总结
虽然分块在时间复杂度上往往劣于线段树, 但分块通用性更强, 可用于维护不具有可合并性的信息, 而且码量不大、常数较小、思想灵活(分块思想可应用到树、链表等结构上), 具有广泛的应用价值和重要的学习意义.
- 标题: 算法学习笔记 -- 数列分块
- 作者: Coast23
- 创建于 : 2025-09-16 23:09:57
- 更新于 : 2025-09-16 23:39:39
- 链接: https://coast23.github.io/2025/09/16/算法学习笔记-数列分块/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。