数论分块/整除分块简单应用
在解释用途之前,我们要证明一个东西,在 一定时,使
满足的最大的 为 。
先翻译一下:对于一个块内值为 ,则块的右端点最大为 。
Proof.
考虑对于这个块内的每个 都有 ,则 ,所以 ,,又因为 为整数,所以 。
整理一下我们得到了什么:对于 ,我们知道了最大的 ,也知道了这一段的某个相同的值,是不是就可以求和了呢?实际上这也就是其主要应用之一。
【例题 1】UVA11526:
求 。
应用上面的结论,可以得到每一段和每一段的值,直接求和即可。
for(int l=1,r;l<=n;l=r+1){
r = min(n,n/(n/l));
sum += (r-l+1) * (n/l);
}
代码非常简单。
但是我们还不知道它为什么是对的。换句话说,我们需要证明其复杂度,显然看到“分块”,你可以估测其复杂度为根号级别。
我们考虑 的取值,当 时,显然 至多有 个取值。当 时,,显然也只有 个取值。所以总取值至多在 ,所以复杂度为 级别,但是注意到这东西有一个 的常数,所以数论分块的常数是略大的。
【例题 2】P2261 [CQOI2007] 余数求和:
求 。
我们考虑计算后面的式子,此时对于 这一段,贡献为 ,我们可以两个分别求和再相乘。
前面显然是一个等差数列求和,后面直接整除分块做即可。
注意一个 corner case, 时,有除数为 需要特判。
由此可见,数论分块能处理的问题还能拓展到求 的问题。
【例题 3】P3935 Calculating:
这题能给我们一个重要的结论。
首先意识到 就是 的因数个数。显然我们只要求出 就能求出答案。
这个东西怎么求呢?你可以先看一下 P1403 [AHOI2005] 约数研究。发现:
大概解释一下,对于 ,会作为每个 的数的因数,对于 ,会作为每个 的数的因数,总共有 个这样的数字。依次类推。
然后可以用数论分块解决。
【二维整除分块】P2260 [清华集训2012] 模积和:
首先容斥一下,把 的在最后减掉即可。
显然可以数论分块,但是不要忘记还要容斥减掉 的情况,考虑那个怎么算,不妨假设 。
前三项显然平凡,直接数论分块即可,考虑计算 ,这是一个多维的整除分块,我们不妨先看看去掉 后怎么做。
想想我们到底是按什么在分块?是值相同,那么假设当前的 是确定的,也就是说 是确定的,那么我如果要能够把这些项一起算,也就是说要找出最大的 使得其对所有数都成立,显然,。这个结论也可以拓展到多维。
然后平凡。考虑加上 项,我们发现 ,于是计算区间的平方和也显然。
给出代码实现:
for(int l=1,r=n;l<=n;l=r+1){
r = min(n/(n/l),m/(m/l));
sum+=(f(r)-f(l-1)) * (n/l) * (m/l);
}
实际上,结合莫比乌斯反演,整除分块还有很大的应用空间。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】