数论分块/整除分块简单应用
在解释用途之前,我们要证明一个东西,在 $l$ 一定时,使
$$l\le r\le n ,\left \lfloor\dfrac{n}{l} \right \rfloor =\left \lfloor\dfrac{n}{r} \right \rfloor$$
满足的最大的 $r$ 为 $\left \lfloor\dfrac{n}{\left \lfloor\dfrac{n}{l} \right \rfloor} \right \rfloor$。
先翻译一下:对于一个块内值为 $p=\left \lfloor\dfrac{n}{l} \right \rfloor$,则块的右端点最大为 $\left \lfloor\dfrac{n}{p} \right \rfloor$。
Proof.
考虑对于这个块内的每个 $x$ 都有 $\left \lfloor\dfrac{n}{x} \right \rfloor = p$,则 $n=px+q(0\le q < n)$,所以 $n\ge px$,$x\le \dfrac{n}{p}$,又因为 $x$ 为整数,所以 $\max x=\left \lfloor\dfrac{n}{p} \right \rfloor$。
整理一下我们得到了什么:对于 $l$,我们知道了最大的 $r$,也知道了这一段的某个相同的值,是不是就可以求和了呢?实际上这也就是其主要应用之一。
【例题 1】UVA11526:
求 $\sum_{i=1}^{n} \left \lfloor \dfrac{n}{i} \right \rfloor $。
应用上面的结论,可以得到每一段和每一段的值,直接求和即可。
for(int l=1,r;l<=n;l=r+1){
r = min(n,n/(n/l));
sum += (r-l+1) * (n/l);
}
代码非常简单。
但是我们还不知道它为什么是对的。换句话说,我们需要证明其复杂度,显然看到“分块”,你可以估测其复杂度为根号级别。
我们考虑 $\left \lfloor \dfrac{n}{i} \right \rfloor$ 的取值,当 $i\le\sqrt{n}$ 时,显然 $\left \lfloor \dfrac{n}{i} \right \rfloor$ 至多有 $\sqrt{n}$ 个取值。当 $i\ge \sqrt{n}$ 时,$\left \lfloor \dfrac{n}{i} \right \rfloor \le \sqrt{n}$,显然也只有 $\sqrt{n}$ 个取值。所以总取值至多在 $2\sqrt{n}$,所以复杂度为 $\sqrt{n}$ 级别,但是注意到这东西有一个 $2$ 的常数,所以数论分块的常数是略大的。
【例题 2】P2261 [CQOI2007] 余数求和:
求 $\sum_{i=1}^{n} k \bmod i $。
$$ \begin{aligned} &\sum_{i = 1}^{n} k \bmod i \\ = &\sum_{i = 1}^{n} (k-i\left \lfloor \dfrac{k}{i} \right \rfloor ) \\ = &\sum_{i = 1}^{n} k - \sum_{i = 1}^{n}(i\left \lfloor \dfrac{k}{i} \right \rfloor) \\ = & nk - \sum_{i = 1}^{n}(i\left \lfloor \dfrac{k}{i} \right \rfloor) \end{aligned} $$
我们考虑计算后面的式子,此时对于 $l\le r$ 这一段,贡献为 $\sum_{i=l}^{r}i\left \lfloor \dfrac{k}{i} \right \rfloor$,我们可以两个分别求和再相乘。
前面显然是一个等差数列求和,后面直接整除分块做即可。
注意一个 corner case,$n>k$ 时,有除数为 $0$ 需要特判。
由此可见,数论分块能处理的问题还能拓展到求 $\sum_{i=1}^{n} f(i)\left \lfloor \dfrac{n}{i} \right \rfloor $ 的问题。
【例题 3】P3935 Calculating:
这题能给我们一个重要的结论。
首先意识到 $f(i)$ 就是 $i$ 的因数个数。显然我们只要求出 $\sum_{i=1}^{n}f(i)$ 就能求出答案。
这个东西怎么求呢?你可以先看一下 P1403 [AHOI2005] 约数研究。发现:
$$\sum_{i=1}^{n}f(i)=\sum_{i=1}^{n}\left \lfloor \dfrac{n}{i} \right \rfloor$$
大概解释一下,对于 $1$ ,会作为每个 $n=1k$ 的数的因数,对于 $2$ ,会作为每个 $n=2k$ 的数的因数,总共有 $\left \lfloor \dfrac{n}{2} \right \rfloor$ 个这样的数字。依次类推。
然后可以用数论分块解决。
【二维整除分块】P2260 [清华集训2012] 模积和:
首先容斥一下,把 $i=j$ 的在最后减掉即可。
$$ \begin{aligned} &\sum_{i = 1}^{n} \sum_{j = 1}^{m} (n \bmod i) \times (m \bmod j)\\ =&\sum_{i = 1}^{n} (n-i\left \lfloor \dfrac{n}{i} \right \rfloor ) \times \sum_{j = 1}^{m}(m-j\left \lfloor \dfrac{m}{j} \right \rfloor )\\ \end{aligned} $$
显然可以数论分块,但是不要忘记还要容斥减掉 $i=j$ 的情况,考虑那个怎么算,不妨假设 $n\le m$。
$$\begin{aligned} &\sum_{i = 1}^{n}(n \bmod i) \times (m \bmod i)\\ =&\sum_{i = 1}^{n}(n-i\left \lfloor \dfrac{n}{i} \right \rfloor ) \times (m-i\left \lfloor \dfrac{m}{i} \right \rfloor )\\ =&\sum_{i = 1}^{n} nm - ni\left \lfloor \dfrac{m}{i} \right \rfloor -mi\left \lfloor \dfrac{n}{i} \right \rfloor +i^2\left \lfloor \dfrac{n}{i} \right \rfloor \left \lfloor \dfrac{m}{i} \right \rfloor \end{aligned}$$
前三项显然平凡,直接数论分块即可,考虑计算 $\sum_{i=1}^{n} i^2\left \lfloor \dfrac{n}{i} \right \rfloor \left \lfloor \dfrac{m}{i} \right \rfloor$,这是一个多维的整除分块,我们不妨先看看去掉 $i^2$ 后怎么做。
想想我们到底是按什么在分块?是值相同,那么假设当前的 $l$ 是确定的,也就是说 $r_i$ 是确定的,那么我如果要能够把这些项一起算,也就是说要找出最大的 $r$ 使得其对所有数都成立,显然,$R=\min r_i$。这个结论也可以拓展到多维。
然后平凡。考虑加上 $i^2$ 项,我们发现 $\sum_{i=1}^{n}i^2=\dfrac{n(n+1)(2n+1)}{6}$,于是计算区间的平方和也显然。
给出代码实现:
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);
}
实际上,结合莫比乌斯反演,整除分块还有很大的应用空间。