杜教筛
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杜教筛相关的知识,希望对你有一定的参考价值。
快速求 $S(n) = \sum_{i = 1} ^ n f(i)$ .
设 $g$ 为另外一个函数.
$\begin{aligned} \sum_{i = 1} ^ n (f * g)(i) & = \sum_{i = 1} ^ n \sum_{d | i} f(d) g(\frac{i}{d}) \\ & = \sum_{k = 1} ^ n g(k) \sum_{d} [kd \le n] f(d) & 枚举 \frac{i}{d} \\ & = \sum_{k = 1} ^ n g(k) \sum_{d = 1} ^ {\lfloor \frac{n}{k} \rfloor} f(d) \\ & = \sum_{k = 1} ^ n g(k) S(\lfloor \frac{n}{k} \rfloor) \end{aligned}$ .
$\begin{aligned} g(1) S(n) = \sum_{i = 1} ^ n (f * g)(i) - \sum_{k = 2} ^ n g(k) S(\lfloor \frac{n}{k} \rfloor) \end{aligned}$ . --- 公式1
假如能够找到合适的 $g$ , 支持快速计算 $g$ 的前缀和, 以及 $f * g$ 的前缀和, 就能根据公式1把 $S(n)$ 转化, 计算出 $S(n)$ .
计算莫比乌斯函数的前缀和.
设 $M(n) = \sum_{i = 1} ^ n \mu(i)$ .
我们有 $[n = 1] = \sum_{k | n} \mu(k)$ , 即 $e = \mu * I$ .
代入公式1得 $M(n) = 1 - \sum_{k = 2} ^ n k S(\lfloor \frac{n}{k} \rfloor)$ .
时间复杂度为 $O(n ^ {\frac{3}{4}})$ .
如果能快速预处理前 $O(n ^ {\frac{2}{3}})$ 项 (一般预处理 1000000 项) , 那么复杂度为 $O(n ^ {\frac{2}{3}})$ .
计算欧拉函数的前缀和.
设 $\Phi(n) = \sum_{i = 1} ^ n \phi(i)$ .
$\phi * I = id$ .
代入公式1得 $\Phi(n) = \frac{n(n+1)}{2} - \sum_{k = 2} ^ n k S(\lfloor \frac{n}{k} \rfloor)$ .
[BZOJ 3944] Sum
求 $M(n), \Phi(n), n \le 10 ^ 9$ .
1 const int N = 1000000; 2 3 bool v[N+5]; 4 int pri[N+5], tot; 5 LL sum[2][N+5]; 6 map<int, LL> mem[2]; 7 8 inline LL pre(int n) { return n * (n+1LL) >> 1; } 9 LL calc(int n, int sig) { 10 if (n <= N) return sum[sig][n]; 11 if (mem[sig].count(n)) return mem[sig][n]; 12 LL ans = (!sig ? 1 : pre(n)); 13 for (int l = 2, r; 2 <= l && l <= n; l = r+1) { 14 int w = n / l; 15 r = n / w; 16 ans -= (r-l+1LL) * calc(w, sig); 17 } 18 return mem[sig][n] = ans; 19 } 20 21 int main(void) { 22 v[1] = true, sum[0][1] = sum[1][1] = 1; 23 F(i, 2, N) { 24 if (!v[i]) { 25 pri[++tot] = i; 26 sum[0][i] = -1, sum[1][i] = i-1; 27 } 28 for (int j = 1; j <= tot && i * pri[j] <= N; j++) { 29 v[i * pri[j]] = true; 30 if (i % pri[j] != 0) { 31 sum[0][i * pri[j]] = -sum[0][i]; 32 sum[1][i * pri[j]] = sum[1][i] * (pri[j] - 1); 33 } 34 else { 35 sum[1][i * pri[j]] = sum[1][i] * pri[j]; 36 break; 37 } 38 } 39 } 40 F(i, 1, N) { 41 sum[0][i] += sum[0][i-1]; 42 sum[1][i] += sum[1][i-1]; 43 } 44 45 for (int nT = rd(), cc = 1; cc <= nT; cc++) { 46 int n = rd(); 47 printf("%lld ", calc(n, 1)); 48 printf("%lld\n", calc(n, 0)); 49 } 50 }
[HDU 5608] function
题意
$g(n) = n ^ 2 - 3n + 2 = \sum_{d | n} f(d)$ .
求 $F(n) = \sum_{i = 1} ^ n f_i$ .
分析
$g = f * I$ .
$g(1)F(n) = \sum_{i = 1} ^ n g(i) - \sum_{i = 2} ^ n I(i) F(\lfloor \frac{n}{i} \rfloor)$ .
$F(n) = \sum_{i} (i ^ 2 - 3i + 2) - \sum_{i = 2} ^ n F(\lfloor \frac{n}{i} \rfloor)$ .
预处理时手动反演.
小结
一个化简的模型: $g = f * I$ .
那么 $F(n) = \sum_{i = 1} ^ n g(i) - \sum_{i = 2} ^ n F(\lfloor \frac{n}{i} \rfloor)$ .
[51NOD 1238] 最小公倍数之和
题意
求 $\sum_{i = 1} ^ n \sum_{j = 1} ^ n [i, j]$ .
分析
我想起了一个简化版的问题: $\sum_{i = 1} ^ n [i, n]$ .
$\begin{aligned} \sum_{i = 1} ^ n [i, n] & = n \sum_{i} \frac{i}{(i, n)} & \text{根据 LCM 与 GCD 的关系进行展开} \\ & = n \sum_k \frac{1}{k} \sum_{i} i [k = (i, n)] & \text{枚举 GCD} \\ & = n \sum_k \frac{1}{k} \sum_{i} i [k | i, k | n, \frac{i}{k} \perp \frac{n}{k}] \\ & = n \sum_k \frac{1}{k} \sum_{d} (dk) [d \perp \frac{n}{k}] & \text{枚举} \frac{i}{k} \\ & = n \sum_k \sum_d d [d \perp \frac{n}{k}] \\ & = n \sum_{k | n} \frac{\frac{n}{k} \phi(\frac{n}{k}) + [\frac{n}{k} = 1]}{2} & \text{利用欧拉函数的性质} \\ & = n \sum_{k | n} \frac{k \phi(k) + [k = 1]}{2} & \text{枚举} \frac{n}{k} \end{aligned}$
尝试将该问题与这道题进行联系.
$\begin{aligned} \sum_{i = 1} ^ n \sum_{j = 1} ^ n [i, j] & = \sum_{i = 1} ^ n \sum_{j \le i} [i, j] + \sum_{j = 1} ^ n \sum_{i \le j} [i, j] - \sum_{i = 1} ^ n [i, i] & 相互联系 \\ & = 2 \sum_{i} ^ n \sum_{j} ^ i [i, j] - \frac{n(n+1)}{2} \\ & = 2 \sum_i ^ n i \sum_{k | i} \frac{k \phi(k) + [k = 1]}{2} - \frac{n(n+1)}{2} \\ & = \sum_{i = 1} ^ n i \sum_{k | i} k \phi(k) & 相互抵消 \\ & = \sum_{i = 1} ^ n \sum_{k = 1} ^ {\lfloor \frac{n}{i} \rfloor} (ik) k \phi(k) & 枚举 \frac{i}{k} \\ & = \sum_{i = 1} ^ n i \sum_{k = 1} ^ {\lfloor \frac{n}{i} \rfloor} k ^ 2 \phi(k) \end{aligned}$ .
设 $f(i) = i ^ 2 \phi(i), F(n) = \sum_{i \le n} f(i)$ , 现在要求 $\sum_{i = 1} ^ {n} i F(\lfloor \frac{n}{i} \rfloor)$ , 即考虑怎么计算 $F(n)$ .
尝试构造函数 $g$ , 满足能够快速计算 $g$ 的前缀和以及 $(f * g)$ 的前缀和, 那么我们就可以进行杜教筛.
将 $(f * g)$ 展开看看: $(f * g)(n) = \sum_{d | n} d ^ 2 \phi(d) g(\frac{n}{d})$ .
我们知道 $n = \sum_{d | n} \phi(d)$ , 尝试使 $d ^ 2 g(\frac{n}{d})$ 与 $d$ 无关.
那么令 $g(d) = d ^ 2$ 即 $g = id_2$ , 推导得 $f * id_2 = id_3$ , 所以 $F(n) = \sum_{i = 1} ^ n i ^ 3 - \sum_{i = 2} ^ n i ^ 2 F(\lfloor \frac{n}{i} \rfloor)$
小结
1. 自然数幂求和
$\sum_{k = 1} ^ n k = \frac{n(n+1)}{2}$ .
$\sum_{k = 1} ^ n k ^ 2 = \frac{n(n+1)(2n+1)}{6}$ .
$\sum_{k = 1} ^ n k ^ 3 = (\sum_{k = 1} ^ n k) ^ 2$ .
高阶的自然数幂求和考虑拉格朗日插值法.
2. 处理 $\sum_{i = 1} ^ n \sum_{k | i} f(k)$ .
思路1: 先枚举 $k$ , 再枚举 $i$ .
思路2: 先枚举 $\frac{k}{i}$ , 再枚举 $k$ .
3. $f(i) = i ^ k \phi(i)$ 的问题都可以用本题的方法解决, 可能需要结合自然数幂求和的相关知识.
以上是关于杜教筛的主要内容,如果未能解决你的问题,请参考以下文章