杜教筛


又在抄 oi-wiki...

\[\phi(n)=\sum_i^n \varphi(i) \]

利用 \(id=\varphi * 1\)

\[\begin{aligned} \frac{1}{2}n(n+1)&=\sum_k^n k \\ &=\sum_k^n\sum_{d|k}\varphi(\frac{k}{d}) \\ &=\sum_d^n\sum_{1\leq k\leq n,d|k}\varphi(\frac{k}{d}) \\ &=\sum_d^n\sum_k^{\left\lfloor\frac{n}{d}\right\rfloor}\varphi(k) \\ &=\sum_d^n\phi(\left\lfloor\frac{n}{d}\right\rfloor) \end{aligned} \]

注意到当 \(d=1\) 的时候就是我们想要的 \(\phi(n)\)

即:\(\phi(n)=\frac{1}{2}n(n+1)-\sum_{d\geq 2}\phi(\left\lfloor\frac{n}{d}\right\rfloor)\)

记忆化搜索即可,可证算法复杂度为 \(\mathcal{O}(n^{2/3})\).

一般化

欲求 \(f\) 的前缀和 \(F\),构造出 \(F(n)\) 关于 \(F(\left\lfloor\frac{n}{d}\right\rfloor)\) 的递推式。

\[\begin{aligned} \sum_i \sum_{d|i}g(d)f(\frac{i}{d})=\sum_{i}g(i)F(\left\lfloor\frac{n}{i}\right\rfloor) \\ \Longleftrightarrow \sum_i(f\ast g)(i)=g(1)F(n)+\sum_{i>1}g(i)F(\left\lfloor\frac{n}{i}\right\rfloor) \end{aligned} \]

若能快速求得 \(f\ast g\) 的前缀和以及 \(g\),则可以整除分块来求 \(F(n)\).

试试看!

\(\sum_{i=1}^n\mu(i)\) 的值,其中 \(n\leq 2^{31}-1\).

利用 \(\mu \ast 1=\epsilon\) 即可。