数论分块
数论分块
数论分块可以在 的时间里计算一些有除法下取整的和式。
它主要利用了富比尼定理(Fubini's theorem),将 相同的数打包同时计算。
富比尼定理
又称“算两次”,以意大利数学家圭多·富比尼(Guido Fubini)命名。 富比尼定理的积分形式:只要二重积分 有界,则可以逐次计算二重积分,并且可以交换逐次积分的顺序。 积分号也是特殊的求和号,因此在一般求和中,富比尼定理往往呈现为更换计数顺序,即交换两个求和号。 组合数学中的富比尼定理表现为,用两种不同的方法计算同一个量,从而建立相等关系。
例如这里的双曲线下整点的图片:

图中共分为了 块,这 块整点的最大纵坐标都相同。如果统计整点的个数,可以从纵向计数改为横向计数,直接计算 个矩形即可。
引理 1
略证:
关于证明最后的小方块
QED 是拉丁词组“Quod Erat Demonstrandum”(这就是所要证明的)的缩写,代表证明完毕。现在的 QED 符号通常是 或者 。(维基百科)
引理 2
表示集合 的元素个数
略证:
对于 , 有 种取值
对于 ,有 ,也只有 种取值
综上,得证
具体过程
数论分块的过程大概如下:考虑含有 的求和式子( 为常数)
对于任意一个 ,我们需要找到一个最大的 ,使得 .
此时 .
显然 ,考虑证明 :
不妨设 ,考虑证明当 时, 的最大值为 :
又因为 为整数 所以
利用上述结论,我们每次以 为一块,分块求和即可
例如 「luogu P2261」[CQOI2007]余数求和,.
代码实现
| long long ans = n * k;
for (long long l = 1, r; l <= n;
l = r + 1) { //此处l意同i,r意同j,下个计算区间的l应为上个区间的r+1
if (k / l != 0)
r = min(k / (k / l), n);
else
r = n; // l大于k时
ans -= (k / l) * (r - l + 1) * (l + r) /
2; //这个区间内k/i均相等,对i求和是等差数列求和
}
|
二维数论分块
求
此时可将代码中 r = n/(n/i) 替换成 r = min(n/(n/i), m/(m/i))
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:OI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用