筛法学习笔记
筛法学习笔记
数论函数
定义域为正整数,陪域与值域为复数的函数。
积性函数
- 积性函数:若数论函数 \(f(n)\) 满足 \(f(1) = 1\) 且对于互质的任意 \(a, b \in N^{+}\) 有 \(f(ab) = f(a)f(b)\),则 \(f(n)\) 为积性函数。
- 完全积性函数:若数论函数 \(f(n)\) 满足 \(f(1) = 1\) 且对于任意 \(a, b \in N^{+}\) 有 \(f(ab) = f(a)f(b)\),则 $f(n) 为完全积性函数。完全积性函数是积性函数。
常见积性函数:
- 单位元函数:\(\varepsilon(n) = [n = 1]\)(完全积性)。
- 幂函数:\(\operatorname*{id}_k(n) = n^k\)(完全积性),\(\operatorname*{id}_1(n)\) 通常省略下标记作 \(\operatorname*{id}(n)\)。
- 恒等函数:\(\operatorname*{id}(n) = n\)(完全积性)。
- 常数函数:\(1(n) = 1\)(完全积性)。
- 除数函数:\(\sigma_k(n) = \sum_{d | n} d^k\),其中 \(\sigma_0(n)\) 通常记为 \(d(n)\) 或 \(\tau(n)\),\(\sigma_1(n)\) 记为 \(\sigma(n)\)。
- 欧拉函数:\(\varphi(n) = \sum_{i = 1}^n [i \perp n]\)。
- 莫比乌斯函数:\(\mu(n) = \begin{cases}1 & n = 1 \\ (-1)^k & n = p_1p_2\ldots p_k \\ 0 & \text{otherwise}\end{cases}\),其中 \(p_i\) 表示本质不同的质因子。
假设有两个积性函数 \(f(x), g(x)\),有如下性质:
- \(h(x) = f(x^p)\) 为积性函数。
- \(h(x) = f^p(x)\) 为积性函数。
- \(h(x) = f(x)g(x)\) 为积性函数。
- \(h(x) = (f * g)(x)\) 为积性函数,其中 \(f * g\) 为狄利克雷卷积。
狄利克雷卷积
定义两个数论函数 \(f(n), g(n)\) 的狄利克雷卷积 \(f * g\) 为:
性质:
-
交换律:\(f * g = g * f\),证明:考虑枚举 \(\dfrac{n}{d}\),就能得到 \(g * f\),
-
结合律:\((f * g) * h = f * (g * h)\),证明:换一下枚举顺序即可。
-
分配律:\((f + g) * h = f * h + g * h\),证明:把和式拆开。
-
单位元:单位元函数 \(\varepsilon(n)\) 是狄利克雷卷积的单位元,恒有 \(f * \varepsilon = f\),证明:\(f(n) = \sum_{d | n} \varepsilon(d) f(\dfrac{n}{d}) = \varepsilon(1) f(n) = f(n)\)。
-
等式的性质:\(f = g \iff f * h = g * h\),其中数论函数 \(h(n)\) 要满足 \(h(1) \ne 0\)。
证明:\(f = g \implies f * h = g * h\) 是容易的。考虑证明必要性,反证,设 \(f \ne g \land f * h = g * h\),那么找到最小的 \(x\) 使 \(f(x) \ne g(x)\),有:
\[ \begin{aligned} &(f * h)(x) - (g * h)(x) = ((f - g) * h)(x) \\ =&\sum_{d | x} (f(d) - g(d)) h(\frac{x}{d}) \\ =&(f(x) - g(x)) h(1) \ne 0 \end{aligned} \]矛盾,命题成立。
-
逆元:对于任意一个满足 \(f(1) \ne 0\) 的数论函数 \(f(n)\),都唯一存在其逆元 \(f^{-1}(n)\) 使得 \(f * f^{-1} = \varepsilon\),其逆元为:
\[f^{-1}(n) = \frac{\varepsilon(n) - \sum_{d | n, d \ne 1} f(d) f^{-1}(\frac{n}{d})}{f(1)} \] -
两个积性函数 \(f(n), g(n)\) 的狄利克雷卷积 \(f * g\) 也为积性函数。
证明:\(\forall a, b \in N^{+} \land a \perp b\),有:
\[\begin{aligned} h(a)h(b) =& \sum_{d_1 | a} f(d_1) g(\frac{a}{d_1}) \sum_{d_2 | b} f(d_2) g(\frac{b}{d2}) \\ =& \sum_{d | ab} f(d) g(\frac{ab}{d}) \\ =& h(ab) \end{aligned} \]因为 \(a, b\) 互质,所以每个 \(ab\) 的质因子只会被组合出来一遍,而对于完全积性函数就没有这个性质了。
常见的狄利克雷卷积:
线性筛
对于积性函数 \(f(n)\),线性筛可以在严格 \(\mathcal{O}(n)\) 的时间内求出任意 \(1 \le i \le n\) 的 \(f(i)\)。
要求:\(f(n)\) 是一个积性函数,\(f(p^c)\) 是可以快速求出或维护的。
思想
对于 \(n = \prod_{i = 1}^k p_i^{a_i}\),考虑用其最小的因子 \(p_1\) 把它筛掉,并求出 \(f(n)\),把 \(n\) 分为三类:
- \(n\) 为质数,按照定义求出 \(f(n)\)。
- \(p_1^2 \, |\, n\),说明 \(n\) 与 \(\dfrac{n}{p_1}\) 含的质因子集合相同,通过 \(f(\dfrac{n}{p_1^{a_1}}) f(p_1^{a_1})\) 算出。
- \(p_1^2 \not |\ n\),则 \(f(n) = f(p_1) f(\dfrac{n}{p_1})\)。
实现
考虑如何使 \(n\) 被最小的因子 \(p_1\) 筛,在下面的代码中,当 \(i\) 是 \(j\) 倍数时就跳出循环,这是因为 \(j\) 更大时,\(i \times j\) 的最小因子就不是 \(j\) 了。而每个数都会被其最小因子筛恰好一次,所以时间复杂度是 \(\mathcal{O}(n)\) 的。
代码:
std::vector<int> primes, minp;
void sieve(const int& N) {
minp.assign(N + 1, 0);
for (int i = 2; i <= N; ++i) {
if (!minp[i]) {
minp[i] = i;
primes.push_back(i);
}
for (auto j : primes) {
if (i * j > N) {
break;
}
minp[i * j] = j;
if (j == minp[i]) {
break;
}
}
}
}
筛欧拉函数
将 \(n\) 分解质因数 \(n = \prod_{i = 1}^k p_i^{a_i}\),则 \(\varphi(n) = \prod_{i = 1}^k \dfrac{p_i - 1}{p_i}\)。对于质数 \(p\),\(\varphi(p) = p - 1\)。
考虑 \(n\) 被最小质因子 \(p\) 和 \(n' = \dfrac{n}{p}\) 筛到时的情况:
- \(p^2 \not | \ n\),\(\varphi(n) = \varphi(n') \cdot (p - 1)\)。
- \(p^2 \ | \ n\),\(\varphi(n) = \varphi(n') \cdot p\)。
筛莫比乌斯函数
类似的,考虑 \(n\) 被最小质因子 \(p\) 和 \(n' = \dfrac{n}{p}\) 筛到时:
- \(p^2 \not | \ n\),\(\mu(n) = -\mu(n')\)。
- \(p^2 \ | \ n\),\(\mu(n) = 0\)。
筛约数函数
若 \(n = \prod_{i = 1}^k p_i^{a_i}\),那么 \(d(n) = \prod_{i = 1}^k (a_i + 1)\)。
考虑 \(n\) 被最小质因子 \(p\) 和 \(n' = \dfrac{n}{p}\) 筛到时:
- \(p^2\ |\ n\),记 \(r(n) = \log_p n\),那么 \(r(n) = r(n') + 1\),\(d(n) = d(n') \dfrac{r(n) + 1}{r(n)}\)。
- \(p^2\not |\ n\),则 \(r(n) = 1\),\(d(n) = 2d(n')\)。
筛约数和
有 \(\sigma(n) = \prod_{i = 1}^k \left(\sum_{j = 0}^{a_i} p_i^j \right)\)。
考虑 \(n\) 被最小质因子 \(p\) 和 \(n' = \dfrac{n}{p}\) 筛到时:
- \(p^2 | n\),记 \(s(n) = \prod_{i = 0}^{\log_p n} p^i\),那么 \(s(n) = p \cdot s(n') + 1\),\(\sigma(n) = \sigma(n') \dfrac{s(n)}{s(n')}\)。
- \(p^2 \not | \ n\),则 \(s(n) = p + 1\),\(\sigma(n) = \sigma(n') (p + 1)\)。
数论分块
数论分块,又称整除分块,是下面各类筛法科技的基础,用于计算一些含有除法下取整(或上取整)的和式,比如 \(\sum_{i = 1}f(i)g(\left\lfloor\dfrac{n}{i}\right\rfloor)\)。当可以快速计算 \(f(r) - f(l)\) 和 \(g(x)\) 时,数论分块就能在 \(\mathcal{O}(\sqrt{n})\) 的时间复杂度内计算和式的值。
思想
数论分块的思想是把 \(\left\lfloor\dfrac{n}{i}\right\rfloor\) 相同的 \(i\) 打包在一起计算,而不同的 \(\left\lfloor\dfrac{n}{i}\right\rfloor\) 只有 \(\mathcal{O}(\sqrt{n})\) 个。
证明:当 \(1 \le d \le n\) 时,不同的 \(d\) 只有 \(\mathcal{O}(\sqrt{n})\) 个。
- 当 \(1 \le d \le \sqrt{n}\) 时,不同的 \(d\) 只有 \(\mathcal{O}(\sqrt{n})\) 个,那么不同的 \(\left\lfloor\dfrac{n}{d}\right\rfloor\) 同理。
- 当 \(\sqrt{n} < d \le n\) 时,\(\left\lfloor\dfrac{n}{d}\right\rfloor < \sqrt{n}\),不同的 \(\left\lfloor\dfrac{n}{d}\right\rfloor\) 也只有 \(\mathcal{O}(\sqrt{n})\) 个。
打包的过程中,每次对于左端点 \(L\),要找到满足 \(\left\lfloor\dfrac{n}{L}\right\rfloor = \left\lfloor\dfrac{n}{R}\right\rfloor\) 的最大的 \(R\),有结论 \(R = \left\lfloor\dfrac{n}{\left\lfloor\frac{n}{L}\right\rfloor}\right\rfloor\)。
证明:设 \(k = \left\lfloor\dfrac{n}{L}\right\rfloor\),那么有 \(\left\lfloor\dfrac{n}{j}\right\rfloor = k\),根据下取整定义:
\[k \leq \frac{n}{j} < k + 1 \iff \frac{n}{k + 1} < j \leq \frac{n}{k} \]则 \(j\) 的取值范围为 \(L \le j \le \left\lfloor\dfrac{n}{k}\right\rfloor\),所以 \(R = \left\lfloor\dfrac{n}{\left\lfloor\frac{n}{L}\right\rfloor}\right\rfloor\)。
那么就能写出数论分块的代码:
int ans = 0;
for (int L = 1, R; L <= n; L = R + 1) {
R = n / (n / L);
ans += sumf(L, R) * g(n / L);
}
上取整
我们想打包 \(\left\lceil\dfrac{n}{i}\right\rceil\) 相等的一段区间,因为有 \(\left\lfloor\dfrac{n + i - 1}{i}\right\rfloor = \left\lfloor\dfrac{n - 1}{i}\right\rfloor + 1\),所以相当于对 \(n - 1\) 做下取整数论分块。
Min_25 筛
Min_25 筛是一个在 \(\mathcal{O}(\dfrac{n^{0.75}}{\log n})\) 或 \(\mathcal{O}(n^{1 - \epsilon})\) 的复杂度内解决积性函数前缀和问题的算法。
(什么?你问我复杂度到底是哪个?我不到啊,跑得很快就对了)
要求:函数 \(f(p)\) 和 \(f(p^c)\) 可以快速求值(比如多项式)。
Min_25 筛分两步进行,要先预处理再求和。
下面任何用 \(p\) 字母表示的量都为质数,\(P_i\) 表示第 \(i\) 个质数,特别地 \(P_0 = 1\)。设质数集为 \(\mathbb{P}\),特别地 \(1 \in \mathbb{P}\),\(\operatorname{minp}_i\) 为 \(i\) 的最小质因子。在某些地方会用 \(*\) 来指代一些数字。
Step 1. 预处理
设出完全积性函数 \(f'\) 使得 \(\forall p, f'(p) = f(p)\)。
记 \(g(n, j) = \sum_{i = 1}^n [i \in \mathbb{P} \lor \operatorname{minp}_i > P_j] f'(i)\)。也就是要么 \(i\) 为质数,要么 \(i\) 的最小质因子 \(>P_j\)。
为了求出 \(g(n, j)\),考虑从 \(g(n, j - 1)\) 递推过来,变化就是那些 \(\operatorname{minp}_i = P_j\) 的数不会被 \(g(n, j)\) 算上了。
由于 \(\forall n \in N^{+}, \operatorname{minp}_n^2 \ge n\),所以当 \(P_j > \sqrt{n}\) 时,\(g(n, j) = g(n, j - 1)\)。而 \(P_j \le \sqrt{n}\) 时,用容斥减去最小质因子为 \(P_j\) 的数,钦定 \(i\) 选了 \(P_j\),这样的 \(i\) 的贡献是 \(f'(P_j)\left(g(\dfrac{n}{P_j}, j - 1) - \sum_{i = 1}^{j - 1} f'(P_i)\right)\),减去 \(\sum_{i = 1}^{j - 1} f'(P_i)\) 的原因是,我们钦定了 \(\operatorname{minp}_i = P_j\),就不能含有 \(P_1, P_2, \ldots, P_{j - 1}\) 这些质因数。
在容斥这个地方,\(f'(n)\) 是完全积性函数的好处就体现出来了,每次只需在外面乘上 \(f'(P_j)\) 从而保证 \(g(n, j)\) 只从 \(g(*, j - 1)\) 转移(更好写,空间常数更小),并保证了时间复杂度正确。
所以 \(g(n, j)\) 的转移式为:
这里的 \(\sum_{i = 1}^{j - 1} f'(P_i)\) 可以用 \(g(P_{j - 1}, j - 1)\) 代替,因为 \(g(P_{j - 1}, j - 1)\) 不含 \(\operatorname{minp}_i > P_{j - 1}\) 的合数,所以相当于是 \(\le P_{j - 1}\) 的质数集。
Step2. 求和
设 \(S(n, j) = \sum_{i = 1}^n [\operatorname{minp}_i > P_j] f(i)\),要求的就是 \(S(n, 0) + 1\),因为 \(\operatorname{minp}_1 = 1\),所以 \(S(n, 0)\) 没算上 \(i = 1\),要加上 \(f(1) = 1\)。
接着考虑把 \(S(n, j)\) 内的 \(i\) 分成质数和合数分类讨论。
当 \(i\) 是质数时,贡献为 \(g(n, |P|) - \sum_{k = 1}^j P_k\),这里的 \(g(n, |P|)\) 表示的是所有 \(\le n\) 的质数的 \(f'(i)\) 之和,而 \(f'(i)\) 根据定义在质数 \(i\) 上的值又等于 \(f(i)\),所以是对的。
当 \(i\) 是合数时,考虑枚举它的最小质因子 \(P_k^e\),使 \(P_k \not |\,\, \dfrac{i}{P_k^e}\),则这部分的贡献是:
因为 \(e = 1\) 时 \(P_k\) 已经被质数部分算过了,所以需要加上条件 \([e > 1]\)。
最终 \(S(n, j)\) 的转移式为:
这里要分情况处理的原因是质数部分 \(g(n, j)\) 可以算出所有 \(>\sqrt{n}\) 的 \(f(P_k)\) 的和,而处理合数部分时不会枚举到 \(> \sqrt{n}\) 的 \(P_k\),不然复杂度炸完了。
不会证时间复杂度,但听说是 \(\mathcal{O}(\dfrac{n^{0.75}}{\log n})\) 或 \(\mathcal{O}(n^{1 - \epsilon})\) 的!
Step 3. 实现
有一些实现上的细节,\(g(n, j)\) 的 \(n\) 很大是存不下的,但是有结论:每次用到 \(g\) 都是形如 \(g(\left\lfloor\dfrac{n}{*}\right\rfloor)\) 的形式。证明这个结论只需要证明:
那么记 \(a = (xc + y)b + z\),其中 \(0 \le y < c, 0 \le z < b\),则:
考虑反证,设它们不相等,则 \(yb + z \ge bc \iff z \ge (c - y)b\),因为 \(y < c\) 故 \((c - y)b \ge b\),得出 \(z \ge b\),矛盾。原命题成立。
所以用数论分块把所有不同的 \(\left\lfloor\dfrac{n}{i}\right\rfloor\) 对应的 \(g\) 求出来就行了。用两个数组 \(id_1[k]\) 存 \(k^2 \le n\) 的 \(g(k)\) 和 \(id_2[k]\) 存 \(k^2 \le n\) 的 \(g(\left\lfloor\dfrac{n}{k}\right\rfloor)\) 即可。当访问 \(g(i)\) 时,若 \(i^2 \le n\) 则返回 \(id_1[i]\),若 \(i^2 \ge n\) 则返回 \(id_2\left[\lfloor\dfrac{n}{i}\rfloor\right]\)。
代码:

浙公网安备 33010602011771号