线性筛与积性函数
筛法
当我们需要获取一个区间内的所有素数的时候,我们肯定会想到筛法。
比较常见的是埃氏筛和线性筛。
他们的实现难度不高,但核心思想有所不同。
埃氏筛
考虑一个 \(p \in \mathbb{P}\) 和任意一个一个大于 \(2\) 的正整数 \(x\),\(\forall y = xp, y \notin \mathbb{P}\)。
这就是埃氏筛的核心。筛去每个素数的所有倍数。
上述筛法的时间复杂度为 \(O(n \log \log n)\)。
线性筛
埃氏筛多余的 \(\log\) 出现在有的数字可能有不止一个质因数导致重复筛到。
如何优化掉这个多余的地方呢。
假设我们现在正在筛 \(x\),小于等于 \(x\) 的素数集合是 \(P\)。
那么类似的,\(\forall p \in P, xp \notin \mathbb{P}\)。
但是注意到如果出现了 \(x \mid p\),说明 \(x\) 这个数已经被 \(p\) 给筛过了。那么接下来就没必要继续了。
因为 \(P\) 中的质数从小到大排列,所以 \(x\) 接下来的所有倍数都已经被 \(p\) 筛过,可以直接退出。
那么注意到每个数字只会被自己的最小质因子给筛 \(1\) 次,时间复杂度 \(O(n)\)。
不过线性筛的常数比较大,并且使用 bitset
会让线性筛更慢。
积性函数
积性函数就是可以相乘的函数。
对于一个积性函数,有 \(\forall gcd(a, b) = 1, f(a \times b) = f(a) \times f(b)\)。
常见的积性函数的筛法:
\[\begin{cases}i = 1 & \mu(i) = 1 \newline i \in \mathbb{P} & \mu(i) = -1 \newline i \notin \mathbb{P} \land p \mid i & \mu(i \times p) = 0 \newline i \notin \mathbb{P} \land p \nmid i & \mu(i \times p) = -\mu(i) \end{cases}
\]
\[\begin{cases}i = 1 & \varphi(i) = 1 \newline i \in \mathbb{P} & \varphi(i) = i - 1 \newline p \mid i & \varphi(i \times p) = \varphi(i) \times p \newline p \nmid i & \varphi(i \times p) = \varphi(i) \times \varphi(p) \end{cases}
\]
记 \(g(n)\) 为 \(n\) 最小质因子的次幂。
\[\begin{cases} i = 1 & \tau(i) = 1 \newline i \in \mathbb{P} & \tau(i) = 2, g(i) = 1 \newline p \mid i & \tau(i \times p) = \frac{\tau(i) \times (g(i \times p) + 1)}{g(i) + 1}, g(i \times p) = g(i) + 1 \newline p \nmid i & \tau(i \times p) = \tau(i) \times \tau(p), g(i \times p) = 1 \end{cases}
\]
记 \(g(n)\) 为 \(n\) 的最小质因子的。
\[\begin{cases}
i = 1 & \sigma(i) = 1 \newline
i \in \mathbb{P} & \sigma(i) = i + 1 \newline
\end{cases}\]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix