莫队与分块
【根号分治】
例题:等差数列加
给定一个长度
要求支持两种操作:
-
,表示把所有下标模 等于 的位置全部加上 ; -
,表示查询 当前值。
做法:
对于所有
否则,在
在我们查询的时候,先
这个复杂度是
cin >> n >> q;
int M = 500; //因为根号2e5差不多500
for (int i = 1; i <= q; i++) {
int opt, x;
cin >> opt >> x;
if (opt == 1) {
int y, d;
cin >> y >> d;
if (x <= M)
tag[x][y] += d; //小于等于M,打标记
else
for (int j = y; j <= n; j += x) //暴力修改
a[j] += d;
}
else {
long long ans = a[x];
for (int j = 1; j <= M; j++)
ans += tag[j][x % j];
cout << ans << endl;
}
}
图染色:
给定一张
-
1 x
,表示翻转点 的颜色; -
2 x
,表示查询 有多少个黑色的邻居。
一般图上的根号分治,按照点的度数分类。
做法:
所有点的度数之和为
设一个阈值
对于翻转操作:
修改一个点时,我们同时更新其周围大点的答案。
因为大点个数
(当然,一个点周围的大点有谁肯定要预处理)
对于查询操作:
如果该点为大点,我们在翻转操作的时候已经记录了答案。
如果该点为小点,直接暴力计算邻居。
两个复杂度取平均,
【莫队】
莫队的思想可以概括为:
询问排序,区间移动,离线处理
【基础莫队】
以两道例题说明莫队的思想。
给出一个
前置思路:
我们想要维护一个区间内,每一个数的出现次数。因为这样我们可以用 符合条件数 / 总可能数 得到概率。
这个用线段树不好做,因为两个区间合并难以
但是,我们发现,假设我们已经算出了 cnt[a[l]]--
即可。并且此时 “符合条件数” 的变化同样简单:ans -= cnt[a[l]]
。
同样地,
题解:
把序列进行分块,
分别处理每一块,处理所有左端点在此块的询问。
对于每个询问,我们循环
如果每个时刻
然后此时此刻,我们就可以回答这个
回答完这个问题后,
这个操作中,处理一个询问需要
分块和莫队在此题中的区别:
分块:分出
虽然分块本身只需要
莫队:同样分块,把每个询问先按左端点所在块的编号排序,然后再按右端点排序。
对于左端点在同一个块的询问,一次处理全部:枚举右端点
如果当前枚举到的右端点刚好是某个询问的右端点,就开始调整左端点到这个询问的左端点。
为什么莫队算法也要新建一个
因为分块是每一个询问都新建一次,而莫队是每一个块新建一次。
下面考虑一下莫队具体的时间复杂度。
外层有一个
内层有一个
对于每一个询问,最多使用
一共
所以是
【莫队的代码结构】
莫队的关键词:询问排序,区间移动,离线处理。
我们在代码中对应的:排序的cmp函数,处理区间的del和add函数,把询问存下来的数组。
【莫队的几何意义】
《算法竞赛》(罗勇军、郭卫斌著)上册 P220。
如果把每一个询问
如果只是按
莫队把
【带修莫队】
对于每一个查询,额外记录一个时间戳
先按左端点所在块排序,再按右端点所在块排序,最后按
把每个修改操作提出来变成一个修改操作序列,每次处理询问的
【回滚莫队】
回滚莫队一般用来处理区间扩张很好维护,但是区间收缩不好维护的情况。
例如求最大值。扩张时只需要取 max 即可;但是收缩时,我们需要堆来辅助求出新最大值。
这题就是典型的扩张好求,收缩不好求。
回滚莫队的运行方式
前面的操作方式和基础莫队一样:按照左端点所在块和右端点把所有询问离线排序。
对于所有询问分两类:
-
左右端点在一个块内。直接暴力
。 -
左右端点不在一个块内。(因为按照右端点排序,肯定先处理完了 1 类才处理 2 类)
右端点和基础莫队一样,单调向右移动。
每次处理一个询问,都把左端点的位置重新设为 “询问左端点所在块的下一个块的第一个位置”。
然后开变量记录 :
“询问左端点所在块的下一个块的第一个位置”,“询问右端点” 的所有收缩时不好维护的信息。接下来,把左端点一直向左扩张到询问的左端点,此时可以算出询问的答案。
算完之后,把左端点再一个一个倒退回 “询问左端点所在块的下一个块的第一个位置”,在倒退过程中,顺便维护所有收缩时好维护的信息。等退到位置了,利用之前记录的变量重置所有收缩时不好维护的信息。
因为右端点不变,左端点还是在一个块内来回移动,所以复杂度不变。
(这比用堆来维护更快!)
【练习】
查询区间内有多少对数差不超过
离散化(巧):先把所有数、所有数 - k、所有数 + k 都离散化了,这样就能快速判断。
然后用一个 BIT 维护当前区间内每个数的个数,开一个变量记录个数。然后就是莫队。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!