整除分块
一维情况
在莫比乌斯反演中,我们经常需要计算类似如下的和式:
如果朴素计算的话时间复杂度是的,这个代价对于很多多询问的题目来说是在是太高了,因此我们需要更快的方法。结论:总共只有种不同的取值。
证明:我们首先证明:对于所有的我们都可以找到一个使得:
令:
因此,通过适当地选择我们已经可以让取到个值,因为这些,因此我们进一步推得:对于所有,共有种取值。对于所有的,我们证明对于这些, 的值各不相同,因为假设存在一对相邻的,使得,则:
而事实上因为,,矛盾。因此对于的个,此时也有种取值。
因此总共大约有种取值,证毕。
这样子我们就可以一段一段地计算了,时间复杂度骤降为,但是一段到底到哪里结束呢?
结论:值为的一段结束于。
证明:随着的变大,的值必定单调递减,临界点就是,此时。考虑到此时可能不是整数,因此结束位置为。
推论:所在的一段结束于。
有这两条结论,我们就可以很快地计算一开头和式的值了:
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += (r - l + 1) * (n / l);
}
二维情况
假设,我们有时候还会碰到类似如下的和式:
结论:共有种取值证明:我们可以这样想象:假设有一根数轴表示的不同取值,用个分割点把数轴分成了段(姑且叫它们段),用个分割点在不同的位置把数轴也分成了段(姑且叫它们段),现在把这些段overlay一下,你会发现现在总共有个分割点把数轴分成了段,每一段的取值可能不同(想一下,两个点只有不完全在相同的段和段时计算出来的才可能不一样!)
结论:所在的一段结束于。
证明:类似一维情况。