数论函数与线性筛

数论函数与线性筛

数论函数把正整数映射为某种数值;
积性则允许我们从质数幂的局部信息恢复整个整数上的函数值。

1 从质因数分解到数论函数

算术基本定理把正整数唯一地分解为若干个质数幂,而积性函数进一步把整数上的函数值分解为各个质数幂上的局部贡献。

本章主线:数论函数 → 积性函数 → 质数幂上的局部贡献 → 线性筛的两种递推分支 → 欧拉函数与莫比乌斯函数 → 因数个数与因数和。

线性筛不仅可以批量找出质数,也可以在生成每个合数时顺便递推多种数论函数。


2 数论函数与积性

2.1 数论函数

定义域为正整数集合 N+\mathbb N^+ 的函数称为数论函数,通常写作 f:N+→Sf:\mathbb N^+\to S。

常见例子包括:

  • 欧拉函数 φ(n)\varphi(n):不超过 nn 且与 nn 互质的正整数个数;
  • 莫比乌斯函数 μ(n)\mu(n):描述一个整数的质因数是否重复以及不同质因数的个数;
  • 因数个数函数 d(n)d(n) 或 τ(n)\tau(n);
  • 因数和函数 σ(n)\sigma(n)。
与映射的联系

数论函数本质上是以正整数为定义域的映射。

参见:03_映射

2.2 积性函数

若数论函数 ff 满足 f(1)=1f(1)=1,并且对任意互质的正整数 a,ba,b 都有 f(ab)=f(a)f(b)f(ab)=f(a)f(b),则称 ff 为积性函数。

若不要求 a,ba,b 互质也始终满足这一等式,则称 ff 为完全积性函数。

例如,恒等函数 id⁡(n)=n\operatorname{id}(n)=n 是完全积性函数;而 φ,μ,d,σ\varphi,\mu,d,\sigma 都是积性函数,但通常不是完全积性函数。

这里的互质条件不能省略,例如 d(2)=2d(2)=2,但 d(4)=3≠d(2)d(2)d(4)=3\ne d(2)d(2)。

2.3 质数幂上的局部贡献

设 nn 的标准质因数分解为 n=∏i=1kpiai\displaystyle n=\prod_{i=1}^{k}p_i^{a_i}。

由于不同质数幂两两互质,若 ff 是积性函数,则 f(n)=∏i=1kf(piai)\displaystyle f(n)=\prod_{i=1}^{k}f\left(p_i^{a_i}\right)。

因此,一个积性函数只要确定了所有质数幂 pap^a 上的取值,就确定了它在全部正整数上的取值。

这也是线性筛递推积性函数的基础:加入一个新的质因数时,直接使用积性;增加已有质因数的指数时,只更新对应质数幂的局部贡献。


3 线性筛的统一递推框架

线性筛从小到大枚举整数 ii,再枚举已经得到的质数 pp,生成新整数 i⋅pi\cdot p。

3.1 加入新的质因数

若 p∤ip\nmid i,则 gcd⁡(i,p)=1\gcd(i,p)=1。

对于积性函数 ff,可以直接得到 f(ip)=f(i)f(p)f(ip)=f(i)f(p)。

这相当于在 ii 的质因数分解中加入一个新的质因数 pp。

3.2 增加已有质因数的指数

若 p∣ip\mid i,在线性筛中当前的 pp 就是 ii 的最小质因数。

设 i=mpei=mp^e 且 gcd⁡(m,p)=1\gcd(m,p)=1,则 ip=mpe+1ip=mp^{e+1}。

此时 mm 的贡献不变,只有最小质因数 pp 对应的局部贡献从 f(pe)f(p^e) 变为 f(pe+1)f(p^{e+1}),因此需要根据具体函数单独递推。

代码中的结构统一为:

1
2
3
4
5
6
if( i % p == 0 ) {
// 已有质因数 p 的指数增加
// 根据具体函数递推
break;
}
// 加入新的质因数 p

break 既保证每个合数只由最小质因数筛去一次,也把两种递推情况清楚地区分开来。

并不是所有积性函数都能在不知道额外信息时直接递推。
通常还需要能够在 O(1)O(1) 时间内更新质数幂上的局部贡献,必要时维护指数、质数幂或局部函数值。


4 欧拉函数

4.1 定义与计算公式

欧拉函数 φ(n)\varphi(n) 表示 11 到 nn 中与 nn 互质的正整数个数,并约定 φ(1)=1\varphi(1)=1。

若 n=∏i=1kpiai\displaystyle n=\prod_{i=1}^{k}p_i^{a_i},则 φ(n)=∏i=1kpiai−1(pi−1)=n∏i=1k(1−1pi)\displaystyle \varphi(n) = \prod_{i=1}^{k}p_i^{a_i-1}(p_i-1) = n\prod_{i=1}^{k}\left(1-\frac1{p_i}\right)。

对于质数幂 pap^a,在 11 到 pap^a 中,不与 pap^a 互质的数恰好是 pp 的倍数,因此 φ(pa)=pa−pa−1\varphi(p^a)=p^a-p^{a-1}。

4.2 线性筛递推

设当前生成 i⋅pi\cdot p。

若 p∤ip\nmid i,由积性得到 φ(ip)=φ(i)φ(p)=φ(i)(p−1)\varphi(ip)=\varphi(i)\varphi(p)=\varphi(i)(p-1)。

若 p∣ip\mid i,增加的只是质因数 pp 的指数吗,由于 φ(pe+1)=pφ(pe)\varphi(p^{e+1})=p\varphi(p^e),因此 φ(ip)=pφ(i)\varphi(ip)=p\varphi(i)。

所以

φ(ip)={φ(i)(p−1),p∤i,pφ(i),p∣i.\varphi(ip)= \begin{cases} \varphi(i)(p-1), & p\nmid i,\\ p\varphi(i), & p\mid i. \end{cases}


5 莫比乌斯函数

5.1 定义

莫比乌斯函数定义为

μ(n)={1,n=1,0,n 含有平方质因子,(−1)k,n 是 k 个不同质数的乘积.\mu(n) = \begin{cases} 1, & n=1,\\ 0, & n\text{ 含有平方质因子},\\ (-1)^k, & n\text{ 是 }k\text{ 个不同质数的乘积}. \end{cases}

它只关注质因数是否重复,以及不同质因数个数的奇偶性。

5.2 线性筛递推

若 p∤ip\nmid i,则 ipip 新增了一个不同质因数,所以 μ(ip)=−μ(i)\mu(ip)=-\mu(i)。

若 p∣ip\mid i,则 p2∣ipp^2\mid ip,因此 μ(ip)=0\mu(ip)=0。

所以

μ(ip)={−μ(i),p∤i,0,p∣i.\mu(ip) = \begin{cases} -\mu(i), & p\nmid i,\\ 0, & p\mid i. \end{cases}

莫比乌斯函数在后续反演与互质计数中会把“最大公因数等于 11”转换为因数求和。


6 因数个数与因数和

因数个数和因数和的基本公式已经在 01_整数分解与筛法 中给出,这里只关心它们如何在线性筛中递推。

6.1 因数个数

设 d(i)d(i) 表示 ii 的正因数个数,e(i)e(i) 表示 ii 的最小质因数在标准分解中的指数。

若 p∤ip\nmid i,则加入新的质因数 pp,其指数为 11,所以 d(ip)=2d(i)d(ip)=2d(i)。

若 p∣ip\mid i,设最小质因数 pp 在 ii 中的指数为 ee。原来的局部贡献是 e+1e+1,乘上一个 pp 后变成 e+2e+2,因此 d(ip)=d(i)e+2e+1\displaystyle d(ip)=d(i)\frac{e+2}{e+1},同时需要更新最小质因数指数:e(ip)=e(i)+1e(ip)=e(i)+1。

6.2 因数和

设 σ(i)\sigma(i) 表示 ii 的正因数和。

在线性筛中,再维护 g(i)g(i),表示最小质因数对应的质数幂因数和。若最小质因数为 pp,指数为 ee,则

g(i)=1+p+p2+⋯+pe.g(i)=1+p+p^2+\cdots+p^e.

若 p∤ip\nmid i,则新加入的局部贡献为 1+p1+p,所以 σ(ip)=σ(i)(1+p)\sigma(ip)=\sigma(i)(1+p),并令 g(ip)=1+pg(ip)=1+p。

若 p∣ip\mid i,则 g(ip)=1+p+⋯+pe+1=pg(i)+1g(ip)=1+p+\cdots+p^{e+1}=pg(i)+1

总因数和中其余质因数的贡献不变,因此 σ(ip)=σ(i)g(i)g(ip)\displaystyle \sigma(ip)=\frac{\sigma(i)}{g(i)}g(ip)。

这里的 g(i)g(i) 是最小质因数对应的整段等比和贡献。


7 线性筛实现

7.1 欧拉函数与莫比乌斯函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 线性筛:素数 / phi / mu
int pri[maxn], pcnt;
bool isp[maxn];
ll phi[maxn];
int mu[maxn];
void sieve( int N ) {
pcnt = 0;
fill( isp, isp + N + 1, true );
phi[1] = 1, mu[1] = 1;
for( int i = 2; i <= N; ++ i ) {
if( isp[i] ) pri[++ pcnt] = i, phi[i] = i - 1, mu[i] = -1;
for( int j = 1; j <= pcnt && 1LL * i * pri[j] <= N; ++ j ) {
int p = pri[j];
isp[i * p] = 0;
if( i % p == 0 ) {
phi[i * p] = phi[i] * p;
mu[i * p] = 0;
break;
}
phi[i * p] = phi[i] * ( p - 1 );
mu[i * p] = -mu[i];
}
}
}

时间复杂度为 O(N)O(N),空间复杂度为 O(N)O(N)。

7.2 因数个数与因数和

代码中使用 f[i] 表示因数和 σ(i)\sigma(i),使用 g[i] 表示最小质因数对应的等比和贡献。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 线性筛:因数个数 / 因数和
int pri[maxn], pcnt;
bool isp[maxn];
int d[maxn], e[maxn]; // 因数个数
int f[maxn], g[maxn]; // 因数和
void sieve2( int N ) {
fill( isp + 2, isp + N + 1, true );
d[1] = 1, f[1] = 1, g[1] = 1;
for( ll i = 2; i <= N; ++ i ) {
if( isp[i] ) {
pri[++ pcnt] = i;
e[i] = 1, d[i] = 2;
g[i] = f[i] = i + 1;
}
for( ll j = 1; j <= pcnt && i * pri[j] <= N; ++ j ) {
ll p = pri[j];
isp[i * p] = 0;
if( i % p == 0 ) {
e[i * p] = e[i] + 1;
d[i * p] = d[i] / e[i * p] * ( e[i * p] + 1 );
g[i * p] = g[i] * p + 1;
f[i * p] = f[i] / g[i] * g[i * p];
break;
}
e[i * p] = 1;
d[i * p] = d[i] * 2;
g[i * p] = p + 1;
f[i * p] = f[i] * g[i * p];
}
}
}

模板中 f、g 使用 int;若因数和可能超过范围,应按题目需要调整整数类型或取模。


8 与后续内容的联系

  • 欧拉函数描述模乘法群的大小,并连接欧拉定理、阶与原根;
  • 莫比乌斯函数是莫比乌斯反演和互质计数的核心工具;
  • 积性函数在质数幂上的局部贡献会进一步抽象为狄利克雷卷积;
  • 数论函数的前缀和可以通过整除分块与杜教筛加速计算;
  • 线性筛预处理是多种数论求和算法的基础。

相关内容:


数论函数与线性筛
http://miqiu.space/posts/245080c4/
作者
Miqiu
发布于
2026年7月1日
许可协议