lg根号数据结构
根号数据结构
序列分块
通过将序列分成小段,整块标记,不足整块的暴力,以平衡修改查询的复杂度。
如果两个操作的调用次数有较大差异,可以使用分块维护更多/更少信息来平衡两边的时间复杂度。请注意并非选择“更快”的数据结构就更好,比如树状数组看似更平衡,但是修改和询问的次数不平衡的时候反而不合适。
如果想要不平衡的区间加区间求和,可以把树状数组的那个做法搬到分块上
- LOJ 6278/6279
分块做法
每一个块都维护一个排好序的数组,扫过整块的时候二分,修改的时候整块打 tag,不完整的块就暴力做,然后重新排序。\(\mathcal O(\sqrt n\log n)\)
归并做法
重新排序可以这样做:如果为排序后的数组保存一个 pos,每次修改把排序后数组分开,两边都是有序的,然后用归并排序进行 merge。这时候这一部分就优化为 \(\mathcal O(\sqrt n)\)
现在修改是 \(\mathcal O(S+n/S)\) 查询是 \(\mathcal O(S+n/S\log S)\)
令块长为 \(S=\sqrt{n\log n}\)
- LOJ 6284
事实上,每个整块被查一次之后就肯定变成同一个了。每次询问会增加 \(\mathcal O(1)\) 个坏的块,总共可能产生 \(\mathcal O(\sqrt n+m)\) 个坏的块,总复杂度就是对的。
- P4117
考虑每个数可以被操作的次数有限,故记录每个块的最大值。考虑如何能够均摊 \(\mathcal O(1)\) 枚举,所以我们的目标是某一个值域被枚举之后就不要再枚举它,我们发现当 \(2x\ge max\) 的时候是 ok 的,但是小的时候,我们就亏了,所以有一个技巧是对大的减转化为对全局减对小的加,相当于维护了一个取值区间,分情况提高最小值、减小最大值。
这里还有空间的问题,我们发现每一个块的贡献皆独立,所以我们可以对于每一块跑一遍所有询问,这样桶就可以被重复使用。
值域/操作分块
-
对值域数组的分块
-
操作分块(按时间分块):操作和询问按照时间分为若干块,对于前面所有块,我们把那些影响直接贡献到一个支持快速查询的数据结构上,内部的修改我们只计算他对询问的贡献,这个块的询问跑完之后再固定到数据结构上。
- 1

我们先 \(\mathcal O(nk)\) 得到单点修改之后 delta 的表示。这样可以 \(\mathcal O(1)\) 计算贡献。现在考虑如何固定影响,考虑直接求一遍。
令块长为 \(S\) ,则 \(\mathcal O(nS+kn\frac{n}S)\) ,\(S=\sqrt{nk}\)
- 2: APIO2019 桥梁
没有修改,可以用并查集。这里并不好计算修改对答案的贡献,但是可以利用块内修改很少的特点
- DFS 序分块
对树的 DFS 序进行序列分块。
- 重链剖分+序列分块
对一条长为 \(k\) 的重链进行序列分块,按 \(\sqrt k\) 分块 ,用于优化链修改链查询,不能做子树操作。
- CF925E May Holidays
先转化为链操作,赋予每一个点 \(-v_i\) 的权,考虑进行树链分块。加1减1操作有特殊性,把相邻的数合并之后,我们可以不用二分,只需要维护一个指针。然后边块修改的时候可以用归并,单点修改的时候暴力加了之后二分一下然后插入。
- 简易树分块
在 \(n\) 个点的树上随机撒 \(\sqrt n\) 个点,期望两个关键点之间距离期望为 \(\sqrt n\)
贪心可以将这个变成严格的:按深度排序从大到小扫,若没有标记,就设为关键点并向上跳 \(\sqrt n\) 到另一个点,设为关键点,并把子树内所有点标记了。注意这样需要额外空间。
也可以把关键点的虚树上的点也记作关键点。
只能处理链操作。
- SDOI2022 无处存储
本题是树分块,那是因为本题卡空间 😅 。
- ???
每次上传最后一个零散的块,拼接子节点上传的 B 得到 2B,递归操作。
根号分治
设定一个阈值,对两边的数据采用不同算法。
- P3396 哈希冲突
(很像曾经的一个 T4,算法基本是一样的)
只需要分 \(\sqrt n\) 来做,小于这个的时候维护一个数组,每次暴力改,大于这个的时候每次暴力查。
- P5309 初始化
(这就是那个 T4 😅)
当 \(x\ge \sqrt n\) 的时候,我们可以考虑用分块做 \(\mathcal O(1)\) 修改 \(\mathcal O(\sqrt n)\) 前缀和/或者按时间分块
小于的时候,维护一个数组并求前缀和,每次询问的时候再暴力加上这一个数组的贡献,修改的时候直接暴力算前后缀和。这并非是不容易的。
莫队

那么最优转移就是最短曼哈顿距离哈密顿链。很遗憾,这个问题是 NP 完全的。莫队算法,基于序列分块,尽可能构造一个好的顺序。

- 小 Z 的袜子
典型莫队。
- 组合数前缀和
m 的变化是可以 \(\mathcal O(1)\) 计算的。

其中 \(S(n,m)\) 为答案。这样一来, n 也可以快速变化。
- 树上莫队
求树上路径信息。
考虑写出树的括号序列,在上面莫队。
要注意 lca 虽然在路径上,但是一次都不会被经过。所以当 lca 不是端点的时候,要额外加入,并且此时要全选左/右括号。
- 不删除/不插入莫队
对于同一个块内的询问,先把左指针放块的右端点,每次先移动右指针,然后移动左边指针,然后撤销移动。
(temp note:记录一个数组存储指针的答案。。。)
- WC2022 秃子酋长
可以莫队,用一个 set 来维护。
还可以用链表,不过不支持删除,这样就变成不插入莫队。
- 莫队二次离线
解决转移复杂度大的问题。
这种方法通过预处理 一个点对于一个区间的贡献。F(x,[l,r])=F(x,[1,r])-F(x,[1,l]) 这两者可以分开处理。
本文来自博客园,作者:haozexu,转载请注明原文链接:https://www.cnblogs.com/haozexu/p/18368038

浙公网安备 33010602011771号