欧拉函数详解

本文详细介绍了欧拉函数,它是小于或等于正整数n且与n互质的数的数目。文中给出了不同情况下欧拉函数的求解方法,如n=1、n为质数、n=pk等。还介绍了计算欧拉函数的三种方式,包括分解质因数、Pollard_Rho算法和线筛顺便求,并分析了时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

  • 关于这东西,我们都是几百年前就接触了。
  • 虽然说这东西现在看来很简单了,但是有些公式的证明也不简单,在此做个详解。

定义

  • 在数论,对正整数n,欧拉函数(Euler’s totient function)是小于或等于n的正整数中与n互质的数的数目。
  • 严谨地, φ ( n ) = ∑ i = 1 n δ g c d ( i , n ) 1 \varphi(n)=\sum_{i=1}^n \delta_{gcd(i,n)1} φ(n)=i=1nδgcd(i,n)1 δ \delta δ克罗内克函数)。

求解

n=1
  • 当n=1时, φ ( n ) = 1 \varphi(n)=1 φ(n)=1。因为1与其本身互质。
n=p
  • 如果n=p,即某个质数,则显然 φ ( n ) = n − 1 \varphi(n)=n-1 φ(n)=n1
n= p k p^k pk
  • 如果n没有重复质因子,会是怎样呢?
  • 不妨设 n = p k n=p^k n=pk,其中p为n的唯一质因子。
  • 那么显然,数x与n互质的充要条件是x与p互质。

  • 正难则反。 φ ( n ) \varphi(n) φ(n)= n以内与n互质的数的个数=n-n以内与n不互质的数的个数
  • 那么,n以内与n不互质的数的个数是多少呢?
  • 显然,a与n不互质的充要条件为p|a。因此,n以内与n不互质的数的个数=n以内p的倍数的个数
  • φ ( n ) = n − n p = n − p k − 1 \varphi(n)=n-\frac np=n-p^{k-1} φ(n)=npn=npk1
otherwise
  • 当然,上述情况仅是特殊情况。很多时候,n是有重复质因子的。
  • 不妨设n=a*b,其中gcd(a,b)=1。实际上, φ ( n ) = φ ( a ) ∗ φ ( b ) \varphi(n)=\varphi(a)*\varphi(b) φ(n)=φ(a)φ(b),即 φ \varphi φ为积性函数。
  • 考虑证明一波。

  • 对于gcd(n,m)=1,我们来求一求 φ ( n m ) \varphi(nm) φ(nm)的值。
  • 先把1~nm的所有数画出来:
    1 2 … … r … … m m + 1 m + 2 … … m + r … … 2 m … … ( i − 1 ) m + 1 ( i − 1 ) m + 2 … … ( i − 1 ) m + r … … i m … … ( n − 1 ) m + 1 ( n − 1 ) m + 2 … … ( n − 1 ) m + r … … n m \begin{matrix} 1 & 2 & …… & r & …… & m \\ m+1 & m+2 & …… & m+r & …… & 2m \\ &&…… \\ (i-1)m+1 & (i-1)m+2 & …… & (i-1)m+r & …… & im \\ &&…… \\ (n-1)m+1 & (n-1)m+2 & …… & (n-1)m+r & …… & nm \\ \end{matrix} 1m+1(i1)m+1(n1)m+12m+2(i1)m+2(n1)m+2rm+r(i1)m+r(n1)m+rm2mimnm
  • 如上表,第i行的数为:(i-1)m+1,(i-1)m+2,…,im。

  • 当gcd(a,nm)=1时(n,m满足gcd(n,m)=1),充要条件为gcd(a,n)=gcd(a,m)=1。
  • 对于上表中的某个数(i-1)m+r,我们知道gcd((i-1)m+r,m)=gcd(r,m)。换句话说,这个数与m的gcd,只与它的列数r有关。
  • 因此,总共有 φ ( m ) \varphi(m) φ(m)列数满足与m互质。
  • 下面,我们随便抽出一列数,看看其中有多少个数满足与n互质。

  • 不妨设抽出的是第r列,则该列数为:r,m+r,…,(n-1)m+r。
  • 显然,这可以构成模n的完全剩余系。因为数列0,1,…n-1是完全剩余系,则数列0,m,…,(n-1)m(整体乘m)也是,则数列r,m+r,…,(n-1)m+r(整体右移r位)也是。
  • 然后,我们又知道gcd(x,n)=gcd(x mod n,n);因此,数列r,m+r,…,(n-1)m+r中与n互质的数的个数 = 数列0,1,…n-1中与n互质的数的个数
  • 换句话说,每一列中,与n互质的数的个数均为 φ ( n ) \varphi(n) φ(n)

  • 综上, φ ( n m ) = φ ( n ) φ ( m ) \varphi(nm)=\varphi(n)\varphi(m) φ(nm)=φ(n)φ(m)

计算

分解质因数
  • 根据上述分析,对于 n = p 1 e 1 ∗ p 2 e 2 ∗ . . . ∗ p k e k n=p_1^{e_1}*p_2^{e_2}*...*p_k^{e_k} n=p1e1p2e2...pkek(pi为n的第i个质因子),均有:
    φ ( n ) = φ ( p 1 e 1 ) ∗ φ ( p 2 e 2 ) ∗ . . . ∗ φ ( p k e k ) = ( p 1 e 1 − p 1 e 1 − 1 ) ∗ ( p 2 e 2 − p 2 e 2 − 1 ) ∗ . . . ∗ ( p k e k − p k e k − 1 ) = p 1 e 1 ( 1 − 1 p 1 ) ∗ p 2 e 2 ( 1 − 1 p 2 ) ∗ . . . ∗ p k e k ( 1 − 1 p k ) = n ∗ ( 1 − 1 p 1 ) ∗ ( 1 − 1 p 2 ) ∗ . . . ∗ ( 1 − 1 p k ) \begin{aligned} \varphi(n) & = \varphi(p_1^{e_1})*\varphi(p_2^{e_2})*...*\varphi(p_k^{e_k}) \\ & = (p_1^{e_1}-p_1^{e_1-1})*(p_2^{e_2}-p_2^{e_2-1})*...*(p_k^{e_k}-p_k^{e_k-1})\\ & = p_1^{e_1}(1-\frac 1{p_1})*p_2^{e_2}(1-\frac 1{p_2})*...*p_k^{e_k}(1-\frac 1{p_k})\\ & = n*(1-\frac 1{p_1})*(1-\frac 1{p_2})*...*(1-\frac 1{p_k})\\ \end{aligned} φ(n)=φ(p1e1)φ(p2e2)...φ(pkek)=(p1e1p1e11)(p2e2p2e21)...(pkekpkek1)=p1e1(1p11)p2e2(1p21)...pkek(1pk1)=n(1p11)(1p21)...(1pk1)
  • 因此,我们只需分解一波质因数,套用这个公式即可。
  • 如果调用次数不多、n又不大,我们可以直接 O ( n ) O(\sqrt n) O(n )的时间找pi。
  • 如果调用次数多、n不大,我们就可以先筛一遍质数,然后直接从所有 ≤ n ≤\sqrt n n 的质数中找pi并且不断令n除以pi,并且如果最终n>1,则n本身即为一个质数。

  • 分析一波时间复杂度。
  • 对于区间 [ 1 , n ] [1,\sqrt n] [1,n ],根据素数定理,这里面包含了大约 n ln ⁡ n \frac{\sqrt n}{\ln \sqrt n} lnn n 个质数。
  • 因此,设调用次数为t,则时间复杂度为: O ( t ∗ n ln ⁡ n ) O(t*\frac{\sqrt n}{\ln \sqrt n}) O(tlnn n )
Pollard_Rho
  • 当n比较大、 O ( n ln ⁡ n ) O(\frac{\sqrt n}{\ln \sqrt n}) O(lnn n )的复杂度难以接受时,可以考虑套上Pollard_Rho算法来分解质因数。
  • 单次时间复杂度: O ( n 1 4 ) O(n^{\frac 14}) O(n41)
线筛顺便求
  • 当t较大(比如 1 0 6 10^6 106),而n并非很大(比如 1 0 7 10^7 107),我们使用上述做法的时间复杂度就有些难以接受了。
  • 这激起了我们的思考:能否在线性的时间内预处理出1~n的欧拉函数值?
  • 实际上,我们可以一边线筛,一边处理欧拉函数。

  • 运用这种奇技淫巧需要先证明一个引理:
  • n ∈ N + , p ∈ p r i m e n\in N^+,p\in prime nN+,pprime,有: φ ( n p ) = { φ ( n ) ∗ φ ( p ) , if  p ∤ n φ ( n ) ∗ p , if  p ∣ n \varphi(np) = \begin{cases} \varphi(n)*\varphi(p), & \text{if $p\nmid n$} \\ \varphi(n)*p, & \text{if $p\mid n$} \end{cases} φ(np)={φ(n)φ(p),φ(n)p,if pnif pn
  • 第一个很好证。既然 p ∈ p r i m e   ∧   p ∤ n p\in prime\ \land \ p\nmid n pprime  pn,那么p与n肯定互质。
  • 关键在于第二个。

  • 第二个的条件是 p ∣ n p\mid n pn
  • 这东西很重要。正因如此,若某个数x满足gcd(x,p)>1,则肯定满足gcd(x,n)>1(毕竟n为p的倍数)。所以,gcd(x,np)=1的充要条件为gcd(x,n)=1。
  • 因此,原问题(求区间[1,np]中有多少个数与np互质)转化成:求区间[1,np]中有多少个数与n互质

  • 对于区间[1,n],其中与n互质的数的个数显然为 φ ( n ) \varphi(n) φ(n)
  • 对于区间[n+1,2n],其中与n互质的数的个数也为 φ ( n ) \varphi(n) φ(n)。因为: g c d ( n + 1 , n ) = g c d ( 1 , n ) , g c d ( n + 2 , n ) = g c d ( 2 , n ) , . . . , g c d ( 2 n , n ) = g c d ( n , n ) gcd(n+1,n)=gcd(1,n),gcd(n+2,n)=gcd(2,n),...,gcd(2n,n)=gcd(n,n) gcd(n+1,n)=gcd(1,n),gcd(n+2,n)=gcd(2,n),...,gcd(2n,n)=gcd(n,n)
  • 那么以此类推,对于第i个区间[(i-1)n+1,in],其中与n互质的数的个数也为 φ ( n ) \varphi(n) φ(n)
  • 而[1,np]中有p个这样的区间,每个里面与n互质的数的个数均为 φ ( n ) \varphi(n) φ(n),因此, φ ( n p ) = φ ( n ) ∗ p \varphi(np)=\varphi(n)*p φ(np)=φ(n)p

  • 然后,我们在线筛的时候,是会枚举一个i,再枚举一个素数x。我们会标记i*x为合数。
  • 此时,若 x ∤ i x\nmid i xi,我们令 φ ( i x ) = φ ( i ) ∗ φ ( x ) = φ ( i ) ∗ ( x − 1 ) \varphi(ix)=\varphi(i)*\varphi(x)=\varphi(i)*(x-1) φ(ix)=φ(i)φ(x)=φ(i)(x1)
  • x ∣ i x\mid i xi,我们要break,跳出枚举x的循环;那么在break之前,先让 φ ( i x ) = φ ( i ) ∗ x \varphi(ix)=\varphi(i)*x φ(ix)=φ(i)x
  • 至此,我们可以在 O ( n ) O(n) O(n)的时间内处理出 φ ( 1 ) , φ ( 2 ) , . . . , φ ( n ) \varphi(1),\varphi(2),...,\varphi(n) φ(1),φ(2),...,φ(n)的值了。
Code
phi[1]=1;
fo(i,2,A)//处理1~A的欧拉函数
{
	if(!com[i]) phi[p[++cnt]=i]=i-1;//若i为质数,则phi[i]=i-1
	for(j=1; j<=cnt&&1ll*i*(x=p[j])<=A; j++)//枚举第j个质数,记它为x
	{
		com[i*x]=1;//标记i*x为合数
		if(i%x==0) {phi[i*x]=x*phi[i]; break;}//若x|i的操作
		phi[i*x]=phi[i]*(x-1);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值