另一个 $O(n(\log \log n)^2)$ 的 Dirichlet 卷积算法

本文是 这篇博客 中的算法的一个变体.

我们首先定义 正交 Dirichlet 卷积 的概念:

\[(f \star g)(n) = \sum_{\substack{ab=n\\a\perp b}} f(a)g(b). \]

观察. 正交 Dirichlet 卷积可以在 \(O(n (\log \log n)^2)\) 时间内计算.

证明. 这是子集卷积道理. 正交 Dirichlet 卷积可以写作

\[(f \star g)(n) = \sum_{\operatorname{lcm}(a,b)=n} [\omega(a)+\omega(b) = \omega(n)] f(a)g(b), \]

其中 \(\omega\) 是质因子数量.

所以用 \(\omega(\bullet)\) 占位, 做整除关系的半格卷积, 可以在 \(O(n (\log \log n)^2)\) 时间内计算正交 Dirichlet 卷积.

复杂度要算一下. 要注意做 Zeta 变换的时候复杂度是 \(\sum_p s(n/p)\), 其中 \(s(n) = \sum_{x\leq n} \omega(x) = \sum n/p = O(n\log \log n)\).

而子集卷积对着点乘部分的复杂度是 \(\sum_{x\leq n} \omega(x)^2 \leq O(\sum_{p,q\leq n} (n/pq)) = O(n(\log \log n)^2)\). \(\square\)

推论. Dirichlet 卷积可以在同样的时间内计算.

证明. 对于贡献 \(a, b \mapsto n = ab\), 我们可以将其分解为公共部分 \(g = \gcd(a, b)\) 和正交部分 \(a/g, b/g\).

所以枚举 \(g\leq \sqrt n\), 所有下标整除 \(g\) 的部分对应的正交卷积, 贡献给 \(g^2\) 倍数的下标部分.

由于正交卷积的时间复杂度是 \(T(n)=O(n (\log \log n)^2)\), 所以 Dirichlet 卷积的时间复杂度在

\[\sum_{g\leq \sqrt n} T(n/g^2) = O(n (\log \log n)^2). \square \]

posted @ 2025-03-26 23:35  EntropyIncreaser  阅读(1429)  评论(0)    收藏  举报