<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Algorithm on</title><link>https://topology2333.github.io/blog/categories/algorithm/</link><description>Recent content in Algorithm on</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sun, 04 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://topology2333.github.io/blog/categories/algorithm/index.xml" rel="self" type="application/rss+xml"/><item><title>质数筛</title><link>https://topology2333.github.io/blog/posts/math/eular-shieve/</link><pubDate>Sun, 04 Jan 2026 00:00:00 +0000</pubDate><guid>https://topology2333.github.io/blog/posts/math/eular-shieve/</guid><description>&lt;h2 id="两种筛的分析">两种筛的分析&lt;/h2>
&lt;blockquote>
&lt;p>感谢 @&lt;a href="https://github.com/LS-Hower">LS-Hower&lt;/a> 的勘误&lt;/p>
&lt;/blockquote>
&lt;h3 id="埃拉托斯特尼筛">埃拉托斯特尼筛&lt;/h3>
&lt;p>对于每一个质数 $p$，标记其倍数 $p^2,p(p+1),p(p+2)\cdots$，对于足够大的 $n$ 和固定的 $p$，标记次数约为
&lt;/p>
$$T(n)\sim \sum_{p\le n} \frac{n}{p} = n\sum _{p\le n}\frac{1}{p}$$
&lt;p>
利用质数调和级数的渐近式
&lt;/p>
$$\sum _{p\le n} \frac{1}{p} = \log\log n+B+o(1)$$
&lt;p>
从而 $T(n)=n\log\log(n)$。有一个 $\log\log n$ 的因子，说明重复访问。&lt;/p>
&lt;hr>
&lt;h3 id="欧拉筛">欧拉筛&lt;/h3>
&lt;p>记 $\text{lp}(n)$ 为 $n$ 的最小质因子（&lt;em>least prime factor&lt;/em>）。由最小质因数引入划分 $\mathcal{L}_p=\{n\ge 2;\text{lp}(n)=p\}$。&lt;/p>
&lt;p>由二元对 $(n,p)$ 双射地标记一个合数 $x=n\times p$，满足性质 $\text{lp}(x)=p$。&lt;/p>
&lt;p>为了给出遍历算法，我们让 $n$ 自然生长，而限制 $p\in \mathcal{P}$ 的范围 $p\le \text{lp}(n)$，以保持 $\text{lp}(x)=p$ 的性质。每个合数仅被其最小质因子筛去一次，因此算法时间复杂度为 $O(n)$。&lt;/p>
&lt;hr>
&lt;dl>
&lt;dt>$p\le \text{lp}(n)$ 的证明&lt;/dt>
&lt;dd>设 $p_n:=\text{lp}(n)$，那么 $\text{lp}(n\times p)=\min\{p,p_n\} = p$，说明当 $p \leq \text{lp}(n)$ 时，性质得到延续。&lt;/dd>
&lt;dd>若 $p\gt p_n$，$\text{lp}(n\times p)=\min\{p,p_n\} = p_n\neq p$，性质被破坏。此时得到的合数 $n\times p$ 应该隶属于 $\mathcal{L}_{p_n}$ 而非 $\mathcal{L}_p$，因此不应继续用更大的质数去枚举这个 $n$ 的后继标记。&lt;/dd>
&lt;/dl>
&lt;hr>
&lt;h2 id="积性函数的自然分解">积性函数的自然分解&lt;/h2>
&lt;h3 id="基本概念">基本概念&lt;/h3>
&lt;p>$f:\mathbb{N}\to \mathbb{C}$ 称积性的，如果对于互质的 $m,n$，$f(mn) = f(m)f(n)$。&lt;br>
如果对所有 $m,n$ 都满足，则称为完全积性的。&lt;/p>
&lt;p>定义狄利克雷卷积&lt;/p>
$$ (f*g)(n):= \sum_{d \mid n}f(d)g \Big(\frac{n}{d} \Big ) $$
&lt;p>狄利克雷卷积可以保持积性。&lt;/p>
&lt;p>定义 $\varepsilon := \llbracket n=1\rrbracket, 1(n) = 1, \text{id}(n)=n$，那么 $1*\mu=\varepsilon, 1*1=\tau, \text{id}*1=\sigma, 1*\varphi=\text{id}$&lt;/p>
&lt;hr>
&lt;h2 id="一点代码">一点代码&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="k">fn&lt;/span> &lt;span class="nf">linear_sieve&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>: &lt;span class="kt">usize&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>-&amp;gt; &lt;span class="p">(&lt;/span>&lt;span class="nb">Vec&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">usize&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">Vec&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">usize&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">lp&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="fm">vec!&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="k">usize&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">];&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// least prime factor
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">primes&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">Vec&lt;/span>::&lt;span class="n">new&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">..=&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">lp&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">lp&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">primes&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">primes&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">lp&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">lp&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lp&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">primes&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-haskell" data-lang="haskell">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nn">Control.Monad&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nn">Control.Monad.ST&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nn">Data.Array.ST&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nn">Data.Array.Unboxed&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">linearSieve&lt;/span> &lt;span class="ow">::&lt;/span> &lt;span class="kt">Int&lt;/span> &lt;span class="ow">-&amp;gt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">UArray&lt;/span> &lt;span class="kt">Int&lt;/span> &lt;span class="kt">Int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="kt">Int&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">linearSieve&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="ow">=&lt;/span> &lt;span class="n">runST&lt;/span> &lt;span class="o">$&lt;/span> &lt;span class="kr">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lp&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">newArray&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="ow">::&lt;/span> &lt;span class="kt">ST&lt;/span> &lt;span class="n">s&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">STUArray&lt;/span> &lt;span class="n">s&lt;/span> &lt;span class="kt">Int&lt;/span> &lt;span class="kt">Int&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">primesRef&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">newSTRef&lt;/span> &lt;span class="kt">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">forM_&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">..&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">$&lt;/span> &lt;span class="nf">\&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="ow">-&amp;gt;&lt;/span> &lt;span class="kr">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">v&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">readArray&lt;/span> &lt;span class="n">lp&lt;/span> &lt;span class="n">i&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">when&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">$&lt;/span> &lt;span class="kr">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">writeArray&lt;/span> &lt;span class="n">lp&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="n">i&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">modifySTRef&lt;/span> &lt;span class="n">primesRef&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="kt">:&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">primes&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">readSTRef&lt;/span> &lt;span class="n">primesRef&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lpi&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">readArray&lt;/span> &lt;span class="n">lp&lt;/span> &lt;span class="n">i&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">forM_&lt;/span> &lt;span class="n">primes&lt;/span> &lt;span class="o">$&lt;/span> &lt;span class="nf">\&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="ow">-&amp;gt;&lt;/span> &lt;span class="kr">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">when&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">lpi&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">p&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">$&lt;/span> &lt;span class="kr">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">writeArray&lt;/span> &lt;span class="n">lp&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">p&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">p&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lp&amp;#39;&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">freeze&lt;/span> &lt;span class="n">lp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">primes&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">fmap&lt;/span> &lt;span class="n">reverse&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">readSTRef&lt;/span> &lt;span class="n">primesRef&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">lp&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">primes&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>