[数论]-----欧拉筛法的应用

欧拉筛法

众所周知欧拉筛法一般用于在线性时间内筛选出 1~n 范围内的质数,但是在数论问题中欧拉筛法的用途不仅仅是筛素数,它还可以干其他三件事,只不过这些问题被提及的次数比较少。
欧拉筛法可以干哪些事呢?

  1. 求 1~n 之间所有质数
  2. 求 1~n 之间所有自然数的欧拉函数 φ(x)
  3. 求 1~n 之间每个数的因子个数
  4. 求 1~n 之间每个数的因数和

1. 筛质数

这个大家应该很熟悉了,这里就写一个关键点吧。
欧拉筛法核心思想:每个合数只被自己的最小质因子筛一次。
对 i%prime[j]==0 时即跳出循环的解释:此时可以令 i = k×prime[j],若不跳出,继续筛 i×prime[j+1] 的话,i×prime[j+1] = k×prime[j]×prime[j+1],它的最小质因子显然是 prime[j] 而不是 prime[j+1],违反了筛法原则。

2. 欧拉函数

欧拉函数 φ(x) 表示小于x的,与 x 互质的数的个数。

积性函数

积性函数指对任意互质的整数 a和b,都有 f(a×b) = f(a)×f(b) 的数论函数
当对任意的整数 a,b 都有 f(a×b) = f(a)×f(b) 时,称 f 为完全积性函数。
欧拉函数是积性函数,但不是完全积性函数。
欧拉函数公式:
ϕ ( x ) = x × ∏ i = 1 n ( 1 − 1 P i ) \phi(x) = x\times\prod_{i=1}^n(1-\frac{1}{Pi}) ϕ(x)=x×i=1n(1Pi1)
其中P1,P2…Pn 是 x 的质因子。

质因数分解

根据唯一分解定理,每一个大于等于2的正整数 n 都有:
n = P 1 ω 1 × P 2 ω 2 × ⋅ ⋅ ⋅ P m ω m n=P1^{\omega1} \times P2^{\omega2} \times \cdot\cdot\cdot Pm^{\omega m} n=P1ω1×P2ω2×Pmωm
由于质数间互质,所以 P i ω i Pi^{\omega i} Piωi P j ω j Pj^{\omega j} Pjωj 互质。所以根据欧拉函数的积性:
ϕ ( n ) = ϕ ( P 1 ω 1 × P 2 ω 2 × ⋅ ⋅ ⋅ × P m ω m ) = ϕ ( P 1 ω 1 ) × ϕ ( P 2 ω 2 ) × ⋅ ⋅ ⋅ × ϕ ( P m ω m ) \phi(n) = \phi(P1^{\omega1} \times P2^{\omega2} \times \cdot\cdot\cdot \times Pm^{\omega m}) \\= \phi(P1^{\omega1}) \times \phi(P2^{\omega2}) \times \cdot\cdot\cdot \times \phi(Pm^{\omega m}) ϕ(n)=ϕ(P1ω1×P2ω2××Pmωm)=ϕ(P1ω1)×ϕ(P2ω2)××ϕ(Pmωm)
这个记为(1)式。
欧拉函数还有两个性质:

  1. 当p是质数时, ϕ ( p ) = p − 1 \phi(p) = p-1 ϕ(p)=p1
  2. ϕ ( p k ) = p k − p k − 1 = p k − 1 × ( p − 1 ) \phi(p^k) = p^k-p^{k-1}=p^{k-1} \times (p-1) ϕ(pk)=pkpk1=pk1×(p1)

对性质二的解释:只有一个数的因子不含质数 p 时,才有可能与 p k p^k pk 互质。而小于等于 p k p^k pk 的数中因子包含 p 的数有 p k − 1 p^{k-1} pk1 个,即 1 × p 1 \times p 1×p 2 × p 2 \times p 2×p ⋅ ⋅ ⋅ \cdot\cdot\cdot p k − 1 × p p^{k-1} \times p pk1×p。从总数 p k p^k pk 中把他们去除便剩下了与 p k p^k pk 互质的数。
所以由 (1) 式,可以的到 ϕ ( x ) \phi(x) ϕ(x) 的另一个公式。
ϕ ( x ) = ∏ i = 1 m P i ω i − 1 × ( P i − 1 ) \phi(x)=\prod_{i=1}^mPi^{\omega i-1} \times(Pi-1) ϕ(x)=i=1mPiωi1×(Pi1)

利用欧拉筛法求欧拉函数

分两种情况讨论:
当 i%prime[j] == 0 时,由于之前说明了 prime[j] 是 i×prime[j] 的最小质因子,所以 i×prime[j] 仅比 i 多一个最小质因子 prime[j],即 P1。
ϕ ( i × p r i m e [ j ] ) = P 1 ω 1 − 1 + 1 × ( P 1 − 1 ) × P 2 ω 2 − 1 × ( P 2 − 1 ) × ⋅ ⋅ ⋅ × P m ω m − 1 × ( P m − 1 ) = ϕ ( i ) × P 1 = ϕ ( i ) × p r i m e [ j ] \phi(i \times prime[j])=P_1^{\omega_1-1+1} \times (P_1-1) \times P_2^{\omega_2-1} \times (P_2-1) \times \cdot\cdot\cdot \times P_m^{\omega_m-1} \times (P_m-1)\\=\phi(i) \times P_1 = \phi(i) \times prime[j] ϕ(i×prime[j])=P1ω11+1×(P11)×P2ω21×(P21)××Pmωm1×(Pm1)=ϕ(i)×P1=ϕ(i)×prime[j]
当 i % prime[j] != 0 时,易知此时 i 与 prime[j] 互质,根据积性性质: ϕ ( i × p r i m e [ j ] ) = ϕ ( i ) × ϕ ( p r i m e [ j ] ) = ϕ ( i ) × ( p r i m e [ j ] − 1 ) \phi(i \times prime[j])=\phi(i) \times \phi(prime[j])\\= \phi(i) \times (prime[j]-1) ϕ(i×prime[j])=ϕ(i)×ϕ(prime[j])=ϕ(i)×(prime[j]1)

3. 欧拉筛法求1~n每个数的约数个数

我们用 d ( x ) d(x) d(x) 表示约数个数。
由于: n = P 1 ω 1 × P 2 ω 2 × ⋅ ⋅ ⋅ P m ω m n=P1^{\omega1} \times P2^{\omega2} \times \cdot\cdot\cdot Pm^{\omega m} n=P1ω1×P2ω2×Pmωm ,考虑 n 的因数的因式分解: ω 1 \omega1 ω1可以有 0,1,2 … ω 1 \omega1 ω1,共 ω 1 + 1 \omega1+1 ω1+1 种选择。同理, ω 2 \omega2 ω2 ω 3 \omega3 ω3 ⋅ ⋅ ⋅ \cdot\cdot\cdot 都有 ω 2 + 1 \omega2+1 ω2+1 ω 3 + 1 \omega3+1 ω3+1 ⋅ ⋅ ⋅ \cdot\cdot\cdot 种选择。根据乘法原理有:
d ( x ) = ( 1 + ω 1 ) × ( 1 + ω 2 ) × ⋅ ⋅ ⋅ × ( 1 + ω m ) d(x) = (1+\omega_1) \times (1+\omega_2) \times \cdot\cdot\cdot \times (1+\omega_m) d(x)=(1+ω1)×(1+ω2)××(1+ωm)
同样分两种情况讨论。
当 i%prime[j] == 0 时
由于 prime[j] 是 i×prime[j] 的最小质因子,所以在对 i×prime[j] 进行因式分解时, ω 1 \omega1 ω1 可以有多一种选择。
d ( i ) = ( 1 + ω 1 ) × ( 1 + ω 2 ) × ⋅ ⋅ ⋅ × ( 1 + ω m ) d(i) = (1+\omega_1) \times (1+\omega_2) \times \cdot\cdot\cdot \times (1+\omega_m) d(i)=(1+ω1)×(1+ω2)××(1+ωm) 时,

d ( i × p r i m e [ j ] ) = ( 2 + ω 1 ) × ( 1 + ω 2 ) × ⋅ ⋅ ⋅ × ( 1 + ω m ) d(i \times prime[j]) = (2+\omega_1) \times (1+\omega_2) \times \cdot\cdot\cdot \times (1+\omega_m) d(i×prime[j])=(2+ω1)×(1+ω2)××(1+ωm)

另外用一个数组 omega[i],保存 i 的最小质因子的个数。
所以:
d ( i × p r i m e [ j ] ) = d ( i ) / ( o m e g a [ i ] + 1 ) × ( o m e g a [ i ] + 2 ) d(i \times prime[j])=d(i) / (omega[i]+1) \times (omega[i]+2) d(i×prime[j])=d(i)/(omega[i]+1)×(omega[i]+2)
同时 o m e g a [ i × p r i m e [ j ] ] = o m e g a [ i ] + 1 omega[i \times prime[j]]=omega[i]+1 omega[i×prime[j]]=omega[i]+1
当 i%prime[j] != 0 时
此时 i × p r i m e [ j ] i \times prime[j] i×prime[j] 的所有因子可以分成两部分,一部分是所有 i 的因子;另一部分是每一个 i 的因子乘以 p r i m e [ j ] prime[j] prime[j] ,可以看出两部分数值上相等,所以 d ( i × p r i m e [ j ] ) = d ( i ) × 2 d(i \times prime[j])=d(i) \times 2 d(i×prime[j])=d(i)×2

4. 欧拉筛法求约数和

我们用 S(n) 来表示 n 的所有约数之和。
公式:
S ( n ) = ( 1 + P 1 + P 1 2 + ⋅ ⋅ ⋅ + P 1 ω 1 ) × ( 1 + P 2 + P 2 2 + ⋅ ⋅ ⋅ + P 2 ω 2 ) × ⋅ ⋅ ⋅ × ( 1 + P m + P m 2 + ⋅ ⋅ ⋅ + P m ω m ) S(n)=(1+P_1+P_1^{2}+\cdot\cdot\cdot+P_1^{\omega_1}) \times\\(1+P_2+P_2^{2}+\cdot\cdot\cdot+P_2^{\omega_2}) \times \cdot\cdot\cdot \times\\(1+P_m+P_m^{2}+\cdot\cdot\cdot+P_m^{\omega_m}) S(n)=(1+P1+P12++P1ω1)×(1+P2+P22++P2ω2)××(1+Pm+Pm2++Pmωm)
证明略。
p s u m [ i ] psum[i] psum[i] 表示 i 的最小质因子 p 的一个形如 1 + P + P 2 + ⋅ ⋅ ⋅ + P ω 1+P+P^2+\cdot\cdot\cdot+P^{\omega} 1+P+P2++Pω 的等比数列的和。
仍然分两种情况,i % prime[j] == 0 时:
S ( i × p r i m e [ j ] ) = ( 1 + P 1 + P 1 2 + ⋅ ⋅ ⋅ + P 1 ω 1 + P 1 ω 1 + 1 ) × ( 1 + P 2 + P 2 2 + ⋅ ⋅ ⋅ + P 2 ω 2 ) × ⋅ ⋅ ⋅ × ( 1 + P m + P m 2 + ⋅ ⋅ ⋅ + P m ω m ) S(i \times prime[j])=(1+P_1+P_1^{2}+ \cdot\cdot\cdot +P_1^{\omega_1}+ P_1^{\omega_1+1}) \times\\ (1+P_2+P_2^{2}+ \cdot\cdot\cdot+ P_2^{\omega_2}) \times \cdot\cdot\cdot \times (1+P_m+P_m^{2}+ \cdot\cdot\cdot+ P_m^{\omega_m}) S(i×prime[j])=(1+P1+P12++P1ω1+P1ω1+1)×(1+P2+P22++P2ω2)××(1+Pm+Pm2++Pmωm)
由于 p r i m e [ j ] prime[j] prime[j] 就是 i × p r i m e [ j ] i \times prime[j] i×prime[j] 的最小质因子,
此时: p s u m [ i × p r i m e [ j ] ] = p s u m [ i ] ∗ p r i m e [ j ] + 1 psum[i \times prime[j]]=psum[i]*prime[j]+1 psum[i×prime[j]]=psum[i]prime[j]+1
同时: S [ i × p r i m e [ j ] ] = S [ i ] / p s u m [ i ] × p s u m [ i × p r i m e [ j ] ] S[i \times prime[j]]=S[i] / psum[i] \times psum[i \times prime[j]] S[i×prime[j]]=S[i]/psum[i]×psum[i×prime[j]]

i % prime[j] != 0 时:
p s u m [ i × p r i m e [ j ] ] = p r i m e [ j ] + 1 psum[i \times prime[j]]=prime[j]+1 psum[i×prime[j]]=prime[j]+1
S [ i × p r i m e [ j ] ] = S [ i ] × p s u m [ i × p r i m e [ j ] ] S[i \times prime[j]]=S[i] \times psum[i \times prime[j]] S[i×prime[j]]=S[i]×psum[i×prime[j]]
(等价于 S [ i ] × ( p r i m e [ j ] + 1 ) S[i] \times (prime[j]+1) S[i]×(prime[j]+1)

5. 代码

#include <cstdio>
int N;
int visit[1001], prime[1001], pa;
int phi[1001];
int sum[1001], d[1001];   //最小质因子个数  因子个数 
int psum[1001], s[1001];  //1+p+p^2...  因数和 
void Euler(int n)
{
	phi[1] = 1;    //1的欧拉函数是1 规定 
	for(int i=2;i<=n;i++)
	{
		if(!visit[i])
		{
			prime[pa++] = i;
			phi[i] = i-1;       //素数的欧拉函数phi[i] = i-1 
			d[i] = 2;           //素数的因子只有1和本身 
			sum[i] = 1;         //素数的最小质因子是自己 
			psum[i] = i+1;      //只有一个质因子且指数为1 
			s[i] = i+1;         //i的因子有 1 和 i 两个 因数和 i+1 
		}
		for(int j=0;j<pa&&i*prime[j]<=n;j++)
		{
			visit[i*prime[j]] = 1;
			if(i%prime[j]==0)
			{
				phi[i*prime[j]] = phi[i]*prime[j];
				sum[i*prime[j]] = sum[i]+1;
				d[i*prime[j]] = d[i]/(sum[i]+1)*(sum[i]+2);
				psum[i*prime[j]] = psum[i]*prime[j]+1;
				s[i*prime[j]] = s[i]/psum[i]*psum[i*prime[j]];
				break;
			}
			phi[i*prime[j]] = phi[i]*(prime[j]-1);
			sum[i*prime[j]] = 1;
			d[i*prime[j]] = d[i]*2;     //i本身的因子 i的每个因子*prime[j]
			psum[i*prime[j]] = 1+prime[j];
			s[i*prime[j]] = s[i]*(1+prime[j]); 
		}
	}
}
void test(int n)
{
	for(int i=2;i<=n;i++)
	{
		printf("%d: \n", i);
		if(!visit[i])
		    printf("%d是素数\n", i);
		else
		    printf("%d不是素数\n", i);
		printf("%d的欧拉函数phi[%d]=%d\n", i, i, phi[i]);
		printf("%d的因子个数为%d\n", i, d[i]);
		printf("%d的所有因子和为%d\n", i, s[i]);
	}
}
int main()
{
	Euler(100);
	test(100);
	return 0;
}

6. 例题

筛素数: 洛谷P3383 【模板】线性筛素数.

求欧拉函数:UVA10299 Relatives.

筛法欧拉函数: SP4141 ETF - Euler Totient Function.

求欧拉函数: 洛谷P2158 [SDOI2008]仪仗队.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
欧拉函数(Euler's Totient Function),也称为积性函数,是指小于等于正整数n的数中与n互质的数的个数。我们通常用φ(n)表示欧拉函数。 具体来说,如果n是一个正整数,那么φ(n)表示小于等于n的正整数中与n互质的数的个数。例如,φ(1)=1,因为1是唯一的小于等于1的正整数且1与1互质;φ(2)=1,因为小于等于2的正整数中只有1与2互质;φ(3)=2,因为小于等于3的正整数中与3互质的数是1和2。 欧拉函数的计算方有很多,下面介绍两种常见的方: 1. 分解质因数 将n分解质因数,假设n的质因数分别为p1, p2, …, pk,则φ(n) = n × (1 - 1/p1) × (1 - 1/p2) × … × (1 - 1/pk)。例如,对于n=30,我们将其分解质因数得到30=2×3×5,则φ(30) = 30 × (1-1/2) × (1-1/3) × (1-1/5) = 8。 2. 筛 我们可以使用筛(Sieve)来计算欧拉函数。具体地,我们可以先将φ(1)至φ(n)全部初始化为其下标值,然后从2开始遍历到n,将所有能被当前遍历到的数整除的数的欧拉函数值减1即可。例如,对于n=6,我们先初始化φ(1)=1, φ(2)=2, φ(3)=3, φ(4)=4, φ(5)=5, φ(6)=6,然后从2开始遍历,将2的倍数的欧拉函数值减1,即φ(4)=φ(6)=2;然后遍历3,将3的倍数的欧拉函数值减1,即φ(6)=2。最终得到φ(1)=1, φ(2)=1, φ(3)=2, φ(4)=2, φ(5)=4, φ(6)=2。 欧拉函数在数论中有很重要的应用,例如RSA算的安全性就基于欧拉函数的难解性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值