杜教筛
又在抄 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\) 即可。