[笔记] 杜教筛
杜教筛
用来在非线性时间内求积性函数前缀和
设现在要求积性函数 \(f\) 的前缀和, 设 \(\sum \limits_{i=1}^{n} f(i) = S(n)\)。
再找一个积性函数 \(g\) ,则考虑它们的狄利克雷卷积的前缀和
\[\sum\limits_{i=1}^{n}(f*g)(i)
\]
\[\begin{aligned} &= \sum\limits_{i=1}^{n} \sum \limits _{d|i} f(d)g(\frac{i}{d}) \\ &= \sum \limits _{d=1}^{n} g(d)\sum\limits _{i=1}^{\lfloor \frac{n}{d}\rfloor } f(i) \\ &= \sum \limits _{d=1}^{n} g(d) S(\lfloor \frac{n}{d} \rfloor) \end{aligned}
\]
再考虑一个式子
\[g(1)S(n)=\sum \limits _{i=1}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor)
\]
所以得到杜教筛的核心式子:
\[g(1)S(n)=\sum\limits_{i=1}^{n}(f*g)(i) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor)
\]
找到一个合适的积性函数 \(g\) ,使得可以快速算出 \(\sum\limits_{i=1}^{n}(f*g)(i)\) 和 \(g\) 的前缀和,便可以用数论分块递归地求解。
inline int F_sum(int n){
if(n <= 5e6) return f[n];
int &sum = n <= m ? F[n] : F[m + ::n / n];
if(sum) return sum; sum = FG_sum(n);
for(int l(2), r; l <= n; l = r + 1)
r = n / (n / l), sum -= (G_sum(r) - G_sum(l - 1)) * F_sum(n / l);
return sum;
}
技巧
-
记忆化:
上面的求和过程中出现的都是 \(\lfloor \frac{n}{i} \rfloor\) 。开一个大小为两倍 \(\sqrt n\) 的数组 \(dp\) 记录答案。
若 \(x \leq \sqrt n\) ,返回
dp[x]
,否则返回dp[sqrt n + n / x]
即可。 -
杜教筛的重点是对于要求的 \(f\),找到 \((f*g)\),满足 \(g,(f*g)\) 的前缀和都很好求出,如果没办法背下常见的狄利克雷卷积结果,不妨直接枚举几个情况试试,来两例子:
- \(f(n)=\mu(n)n^2,g(n)=n^2,(f*g)(n)=[n=1]\);
- \(f(n)=\varphi(n)n^2,g(n)=n^2,(f*g)(n)=n^3\);
题单
开始在想能不能把 i 和 j 分开
因为 \(n\le10^5,m\le10^9\),所以比较自然地想到枚举 \(n\) 去求解,然后开始考虑对某一个 \(n\) 怎么处理。
因为 \(\varphi\) 函数的一些性质:\(n=\prod_{i=1}^qp_i^{c_i},\varphi(n)=\varphi(\prod_{i=1}^qp_i)\prod_{i=1}^qp_i^{c_i-1}\)
考虑先把 \(n\) 的质因数次数高于一次的部分都提出来,记为 \(x\),剩下的 \(\frac{n}{x}\) 记为 \(y\).
\[\begin{aligned}
\sum_{i=1}^m\varphi(ni)
&=x\sum_{i=1}^m\varphi(yi)\\
&=x\sum_{i=1}^m\varphi(\frac{y}{\gcd(y,i)})\varphi(i)\gcd(y,i)\\
&=x\sum_{i=1}^m\varphi(\frac{y}{\gcd(y,i)})\varphi(i)\sum_{j\mid gcd(y,i)}\varphi(j)
\ (这里用的是\ n=\sum_{i\mid n}\varphi(i))\\
&=x\sum_{i=1}^m \varphi(i) \sum_{j\mid \gcd(y,i)}\varphi(\frac{y}{j})
\ (由于\ y\ 的特殊性,y\ 与\ \gcd(y,i)\ 的因数互质,可以直接乘)\\
&=x\sum_{i=1}^m \varphi(i) \sum_{j\mid y,j\mid i}\varphi(\frac{y}{j})
\ (然后对枚举顺序进行一个交换)\\
&=x\sum_{j\mid y}\varphi(\frac{y}{j})\sum_{i=1}^{\frac{m}{j}}\varphi(ji)\ (整理到此处于是可以递归)
\end{aligned}
\]
总之记忆化后,复杂度是对的.