分块学习笔记
分块是什么
先从经典问题引入:
已知一个长为 的数列,你需要进行下面两种操作 次:
- 将某区间每一个数加上 。
- 求出某区间每一个数的和。
对于 的数据,保证 。
最朴素的方法:利用循环结构,对数组内每一个数进行单点加和求值。
显然,当每个区间长度都取到最大值的时候,复杂度为 ,不被我们所接受。
引入分块。
分块,顾名思义就是分成很多块,对于每一块的情况单独处理和维护。
假设我们把一个序列分成很多块,每块长度很小,如果每一次的操作都在一块内,使用前面的暴力做法复杂度是可以接受的。
但是,情况远没有我们想象的这么理想,区间长度总是会很长,其中包含了很多块。
此时,左右部分会有两个块不被完全包含,中间所有的块都被完全包含。
显然,左右部分可以使用暴力,那么中间呢?思考一下...完全包含?我们在线段树中也用过这个方法来保证复杂度,lazytag
。
对散块,暴力修改或求值,对整块,修改就打 lazytag
,求和就把原本记录的整块总和与 lazytag
叠加即可。
假设我们的块长为 ,那么显然会有 个块。
对于两边的散块,我们的最大访问元素数是 个,总和是 个。
对于中间的整块,我们是打 lazytag
,只需要访问每一块整体即可,最多有 个块。
访问次数就是 。
这说明了什么?
我们的复杂度,完全取决于块长。
你块长太小,那么前面的 将会让你飞天,你块长太大,后面的 也会让你飞天。
综合之下,我们一般取 为块长。
例题选讲
分块是需要做很多题来补充自己的卡常方法的。
LOJ #6278. 数列分块入门 2
已知一个长为 的数列,你需要进行下面两种操作 次:
- 将某区间每一个数加上 。
- 求出某区间小于一个数的个数。
对于 的数据,保证 。
对于散块,我们还是暴力计算。 对于整块,我们需要一些技巧。 排序后二分寻找个数。 复杂度 。
P5356 [Ynoi2017] 由乃打扑克
已知一个长为 的数列,你需要进行下面两种操作 次:
- 将某区间每一个数加上 。
- 求出某区间第 小的数。
对于 的数据,保证 。
先二分答案这个值,然后判断是第几小即可。
LOJ #6285. 数列分块入门 9 (https://loj.ac/p/6285)
已知一个长为 的数列,你需要进行下面的询问 次:
- 询问某区间的最小众数。
对于 的数据,保证 。
考虑维护整块答案和连续段整块出现次数,此处可以做到 。
考虑散块答案对整块已有答案影响。
时间复杂度 。
P4135 作诗
已知一个长为 的数列,你需要进行下面的询问 次:
- 询问某区间出现过且出现次数为偶数次的数的个数。
对于 的数据,保证 。
与上一题相同,考虑维护连续整块答案和散块对于整块已有答案的影响。
这里需要开一个桶,为了保证复杂度在 ,不该使用 memset
,将已有操作撤回即可。
CF1620E Replace the Numbers
你有一个数列,初始为空,你需要进行下面的两种操作 次:
- 在数列末尾插入一个数 。
- 将所有值为 的数改为 。
操作结束后输出最终数列。
对于 的数据,保证 。
考虑并查集。
使用一个 表示一个并查集的根所对应的值,使用一个 表示一个值所对应的并查集的根。
改值时,如果值 目前存在,把 (也就是表示值 的并查集所代表的根)合并到 处,并且清空 。
如果值 目前不存在,就把 修改为 ,把 所对应的 修改为 ,并且清空 。
P4117 [Ynoi2018] 五彩斑斓的世界
已知一个长为 的数列,你需要进行下面的两种操作 次:
- 把某区间所有大于 的数减去 。
- 查询某区间 的出现次数。
对于 的数据,保证 。
空间限制
64MB
。
分块照常套路,对于散块暴力减去 ,下面只考虑整块。
把大于 的数减去 ,也就是把所有大于 ,小于等于区间最大值 的值 更改为 。
对于每一个整块建立一个并查集,更改值可以参考上一题的做法。
查询出现次数并查集维护一个 表示 的出现次数即可。
但是直接更改值复杂度是错的。
考虑 且 时,需要进行 次操作。
发现把所有大于 的值全都减去 等价于把所有小于等于 的数全都加上 并区间减 。
上面那个例子,如果使用这种修改方法就极其高效。
考虑综合两种方法。
如果 ,使用第一种方法把大于 小于等于 的数 改为 。
如果 ,使用第二种方法把小于等于 的数 改为 并打上区间减 的 tag
。
显然该办法的作用就是将整体值域左右端点拉近来保证复杂度,所以最大总操作数为 次。
该做法空间复杂度为 ,无法通过,逐块处理即可。
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122052
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下