分块入门详解(比较全面)
最近写了几个分块,顺便做一下笔记。
什么是分块
分块是一种数据结构。。
有许多数据结构都是 数据结构,比如线段树,树状数组等等。他们复杂度优秀,但是都是树形结构,有较大的思维难度和局限性。那么有没有什么复杂度一般,但是非树形的数据结构呢?
有的,就是分块。
分块的思路是把数据分成一个个的小块。设每块长为 。举个栗子:
1, 1, 4, 5, 1, 4 (S = 2)
那么我们就可以把他分成
1, 1 | 4, 5 | 1, 4
我们成功把他分成了三个小块。
对于每个询问 ,它会跨越许多小块和整块。比如对于刚才那个数据:
1, 1 | 4, 5 | 1, 4 (l = 2, r = 5, S = 2)
| |
l -------- r
l, r 跨越了第一块的后半个,第二块和第三块的前半个。
对于整块,我们一般可以用打懒标记之类的方法来搞,一共有 个整块,所以复杂度最坏也是 。对于散块来说,最多会有一左一右两个散块,长度最多为 ,对他们进行暴力操作,复杂度最坏为 。考虑常数,总复杂度为 。(虽然 里面不应该加常数)。根据均值不等式,当 。通常我们取 ,单次操作复杂度稳定在 级别。
分块怎么写
首先先说一下分块的几个重要操作:
- 定位操作。 函数返回 所处的块的编号。可以这样写
int get(x) { return (int)x / S; }
- 查询端点。,返回当前块的左、右端点。可以这样写(前提是你的
get
函数和我一样。)
int getl(int x) { return S * x + (x == 0); }
int getr(int x) { return min(n, (x + 1) * S - 1); }
拿 数列分块入门1 举个栗子。
题意: 给定长度为 的数列,进行 次操作。操作涉及区间加法,单点查询。
这种题当然可以 线段树 / 树状数组
,但是今天我们要用分块来写。按照上面我们说的。借鉴线段树的思路,我们可以维护一个 懒标记,来维护当前块应该加上几。
现在假设我们修改的区间是 ,可能有下面几种情况。
- 左右端点在同一个块里。我们遍历 ,暴力加即可。复杂度
- 左右端点不在同一个块里。我们可以遍历中间的整块并打上懒标记。由于块数不超过 个,所以复杂度也不高。对于不在整块内的边角,直接暴力加就可以。
核心代码
int get(int x) { return x / S; } // 定位当前点在哪个块
void modify(int l, int r, int v) { // 修改操作
int ls = get(l), rs = get(r);
if (ls == rs) { for (int i = l; i <= r; i ++ ) w[i] += v; return; } // 在同一个整块内
int i, j;
for (i = l; get(i) == ls; i ++ ) w[i] += v; // 处理边角
for (j = r; get(j) == rs; j -- ) w[j] += v;
for (int k = get(i); k <= get(j); k ++ ) // 处理整块。
add[k] += v;
}
int main() {
.......
if (query node) printf("%d\n", w[r] + add[get(r)]);
else modify(l, r, v);
}
其他例题
数列分块入门7
题意: 给出一个长为 的数列,以及 个操作,操作涉及区间乘法,区间加法,单点询问。
可以对照线段树2来做。对每个块维护加、乘懒标记。注意:懒标记更新的时候注意顺序,对散块操作的时候要重构整个块。
代码示例
数列分块入门2
题意: 给出一个长为 的数列,以及 个操作,操作涉及区间加法,询问区间内小于某个值 的元素个数。
分块常用的思想,就是在每个块内维护一个有序序列。加操作时可以打懒标记。查询操作可以直接块内二分。单次操作复杂度 ( 和 同阶)
代码示例
数列分块入门5
这道题带插入怎么办呢?块状链表隆重登场!!
块状链表可以看一下我写的博客 块状链表详解
剩下的就不讲了吧,再放几道例题。
例题
-
数列分块全系列
-
某些线段树题(比如洛谷线段树模板)
-
其他题目,如 Luogu 分数统计
以后可能还会加例题。先挖个坑。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示