整除分块
设 \(f(n) = \sum\limits^{n}_{i=1}{\lfloor\frac{n}{i}\rfloor}\) ,给定 \(n, n \in [1, 10^9] \cap \mathbb{Z}\) ,求 \(f(n)\)
算法分析
当 \(n = 20\) 时,有
\(i\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
\(\lfloor\frac{n}{i}\rfloor\) | 20 | 10 | 6 | 5 | 4 | 3 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
可以看出有连续一块都相同的结果。
事实上有不超过 \(2\sqrt n\) 这样的块个。
证明 有不超过 \(2\sqrt n\) 个这样的块。
引理
\(\forall a \in [2, \sqrt n - 1], \lfloor\frac{n}{a}\rfloor > \lfloor\frac{n}{a+1}\rfloor\)
证明:
反证法。显然 \(\lfloor\frac{n}{a}\rfloor \geq \lfloor\frac{n}{a+1}\rfloor\) 。假设 \(\exists a \in [2, \sqrt n - 1], \lfloor\frac{n}{a}\rfloor = \lfloor\frac{n}{a+1}\rfloor = k \geq \sqrt n\)
\(\Rightarrow n = a \cdot k + c_1 = (a + 1) \cdot k + c_2, 0 \leq c_1 < a, 0 \leq c_2 < a + 1\)
\(\Rightarrow a \cdot k + c_1 = a \cdot k + k + c_2\)
\(\Rightarrow c_1 = k + c_2\)
\(\because k \geq \sqrt n, 0 \leq c_2\)
\(\therefore c_1 \geq \sqrt n\)
与 \(c_1 < a < \sqrt n\) 矛盾,原命题得证。
证明
在 \([1, \sqrt n] \cap \mathbb{Z}\) 中取两个数 \(x_1, x_2\) ,且 \(x_1 + 1 = x_2\)
\(y_1 = \lfloor\frac{n}{x_1}\rfloor, y_2 = \lfloor\frac{n}{x_2}\rfloor\) ,则 \(y_2 < y_1\) , 且 \([y_2, y_1] \subseteq [\sqrt n, n]\)
对于 \([y_2 + 1, y_1]\):
-
对于上界 \(y_1\):
\(y_1 = \lfloor\frac{n}{x_1}\rfloor\)
\(\Rightarrow n = y_1 \cdot x_1 + z \Rightarrow z < x_1 < x_2 \leq \sqrt n \leq y_1 \Rightarrow z < y_1\)
\(\Rightarrow \lfloor\frac{n}{y_1}\rfloor = x_1\)
-
对于下界 \(y_2 + 1\):
\(y_2 = \lfloor\frac{n}{x_2}\rfloor\)
\(\Rightarrow n = x_2 \cdot y_2 + z, z < x_2\)
\(\Rightarrow x_2 \cdot (y_2 + 1) > n \Rightarrow x_2 > \lfloor\frac{n}{y_2 + 1}\rfloor \Rightarrow x_1 \geq \lfloor\frac{n}{y_2 + 1}\rfloor\)
\(y_2 + 1 \leq y_1 \Rightarrow \lfloor\frac{n}{y_2 + 1}\rfloor \geq \lfloor\frac{n}{y_1}\rfloor = x_1\)
\(x_1 \geq \lfloor\frac{n}{y_2 + 1}\rfloor \geq x_1 \Rightarrow \lfloor\frac{n}{y_1}\rfloor = x_1\)
综上,\(\forall k \in [y_2 + 1, y_1], \lfloor\frac{n}{k}\rfloor = x_1\)
所以,对于 \(k \in [1, \sqrt n]\) 都有与之对应的 \(\lfloor\frac{n}{k}\rfloor \in [\sqrt n, n]\) ,反过来对于 \(k \in [\sqrt n, n]\) 都有与之对应的 \(\lfloor\frac{n}{k}\rfloor \in [1, \sqrt n]\) ,一共有 \(2\sqrt n\) 个,原命题得证。
左右边界
设 \(l\) 为分块左边界,\(r\) 为分块右边界,\(k = \lfloor\frac{n}{l}\rfloor = \lfloor\frac{n}{r}\rfloor\) ,那么 \(k=\lfloor \frac{n}{l} \rfloor\)。\(r\) 为 \(i\) 最大值, \(i\) 满足 \(\lfloor\frac{n}{i}\rfloor = k\) ,\(n = k \cdot i + z, z \in [0, k) \cap \mathbb{Z}\),所以 \(i = \frac{n-z}{k}\),可得 \(i \leq \lfloor\frac{n}{k}\rfloor\),即 \(r=\max(i)=\lfloor\frac{n}{k}\rfloor\)。将 \(k = \lfloor\frac{n}{l}\rfloor\) 代入,\(r = \lfloor \frac{n}{\lfloor\frac{n}{l}\rfloor} \rfloor\)
代码
将不同的块的数字乘其对应的值,最后相加。一共有 \(O(2 \sqrt n)\) 个块,求对应的值是 \(O(1)\) 的,所以总时间复杂度是 \(O(\sqrt n)\)
int f(int n) {
int res = 0;
for(int l = 1, r; l <= n; l = r + 1)
{
r = n / (n / l);
/* n / l 是当前块对应的值 */
/* r - l + 1 是当前块的长度 */
res += n / l * (r - l + 1);
}
return res;
}
若要求 \(g(n, m) =\sum\limits^n_{i=1}{\lfloor\frac{m}{i}\rfloor}\) ,需要限制围为 \(n\) 。
int h(int n, int m) {
int res = 0;
for(int l = 1, r; l <= n; l = r + 1)
{
if(m / l) // m / l 有可能为 0
r = ::std::min(n, m / (m / l));
else
r = n;
res += m / l * (r - l + 1);
}
return res;
}
例题
#1 - 洛谷 P1403 [AHOI2005] 约数研究
给定 \(n, n \leq 10^9\) ,求 \(\sum\limits^n_{i=1}F(i)\) ,其中 \(F(x)\) 表示 \(x\) 的正因子个数
解法:
对于一个数 \(d\) ,可以成为 \(\lfloor\frac{n}{d}\rfloor\) 个数的因子,靠虑 \(1 \sim n\) 的每一个数 \(d\) ,则答案为 \(\sum\limits^n_{d=1}{\lfloor\frac{n}{d}\rfloor}\) ,即 \(f(n)\)
#2 - 洛谷 P2424 约数和
给定 \(X, Y, X < Y \leq 2 \times 10^9\) ,求 \(\sum\limits^Y_{i=X}{\sum\limits_{j|i}{j}}\),即求 \(X \sim Y\) 每个数的正因子之和。
解法:
计算 \(1 \sim Y\) 和 \(1 \sim X - 1\) 每个数的正因子之和,做差即可。
对于一个数 \(d\) ,可以成为 \(\lfloor\frac{n}{d}\rfloor\) 个数的因子,且贡献都为 \(d\),靠虑 \(1 \sim n\) 的每一个数 \(d\) ,则答案为 \(\sum\limits^n_{d=1}{\lfloor\frac{n}{d}\rfloor \cdot d}\)
对于边界为 \(l, r\) 的块,这个块的贡献是 \(\sum\limits^r_{d=l}{\lfloor\frac{n}{l}\rfloor \cdot d} = \lfloor\frac{n}{l}\rfloor \cdot \sum\limits^r_{d=l}{d} = \lfloor\frac{n}{l}\rfloor \cdot \frac{(r - l + 1)(r - l)}{2}\)
ll calc(ll x) {
ll res = 0;
for(ll l = 1, r; l <= x; l = r + 1)
{
r = x / (x / l);
res += x / l * (r - l + 1) * (l + r) / 2;
}
return res;
}
#3 - 洛谷 P2261 [CQOI2007] 余数求和
给出正整数 \(n\) 和 \(k\),\(n,k \leq 10^9\),计算 \(G(n, k) = \sum\limits_{i = 1}^n{k \bmod i}\)
解法:
\(k \bmod i = k - \lfloor\frac{k}{i}\rfloor \cdot i\)
答案为 \(\sum\limits_{i = 1}^n{(k - \lfloor\frac{k}{i}\rfloor \cdot i)} = nk - \sum\limits_{i = 1}^n{\lfloor\frac{k}{i}\rfloor \cdot i}\) ,这样就和上一个题差不多了,但是要注意边界是 \(n\)
#4 - CF1485 C. Floor and Mod
求 \(a \in [1, x] \cap \mathbb{Z}, y \in [1, y] \cap \mathbb{Z}\) 且 \(\lfloor\frac{a}{b}\rfloor = a \bmod b\) 的 \((a,b)\) 个数。
解法:
由 \((1)\) 式和 \((4)\) 式可得 \(\frac{a}{b + 1} < b \Rightarrow a < b^2 + b \Rightarrow a \leq b^2 + b - 1\),由 \((3)\) 式可得 \((b + 1) | a\),综上满足条件的 \(a\) 有 \(\lfloor\frac{b^2 + b - 1}{b + 1}\rfloor\) 个,且要 \(a \leq y\),则答案为
其中 \(p\) 满足 \((p - 1)^2 + (p - 1) - 1 \leq x < p^2 + p - 1\)
求 \(p\) 与加号左边的式子直接枚举即可,因为 \(p = O(\sqrt n)\) 。加号右边整除分块,即 \(g(y + 1, x) - g(p, x)\)
#5 - 洛谷 P3935 Calculating
若 \(x\) 分解质因数结果为 \(x=p_1^{k_1}p_2^{k_2}\cdots p_n^{k_n}\),令\(F(x)=(k_1+1)(k_2+1)\cdots (k_n+1)\),求 \(\sum\limits_{i=l}^rF(i)\) 对 \(998\,244\,353\) 取模的结果。
\(l \leq r \le 1.6 \times 10^{14}\)
解法:
根据 算数基本定理的推论 可知 \(F(x)\) 就是 \(x\) 的正因子个数,求法和例题1一样,则答案为 \(f(r) - f(l - 1)\),注意取模。