欧拉函数、定理学习笔记

欧拉函数、定理学习笔记

欧拉函数

定义

所有小于等于 x 的数中与 x 互质的数的个数。
符号: φ(x)

通项公式

pi 表示 x 的质因数,n 表示 x 的质因数个数。

φ(x)=xi=1n(11pi)

欧拉函数的性质

对于质数 x,φ(x)=x1

x,y 互质,则 φ(x)×φ(y)=φ(x×y)

这条性质属于积性函数,即任意满足有 互质 的数 a,b 时,恒有 f(a×b)=f(a)×f(b)
(怎么证明我是真的不会,如果真想知道可以看下这个

如果 n 为奇数,则 φ(n×2)=φ(n)

因为 n 为奇数,所以 n 与 2 互质,且 φ(2)=1,所以上式成立。

如果 x 为质数,则φ(xk)=xkxk1

因为与 xk 不互质的数只有 x 的倍数,而 xkx 的倍数有 xk1 个。

如果 3x,则 φ(x) 的值为偶数。

因为 gcd(x,n)=gcd(nx,n) ,更相减损术证明,与 x 互质的数是成对存在的,且每一对中的两个数之和为 x

i=1,(i,x)=1x1i=φ(x)×x2(2x)

通过上面的证明可知,每一对与 x 互质的数的和为 x,总共有 φ(x)2 对。

x=i|xφ(i),即 x 的因数(包括1和它自己)的欧拉函数之和等于 x

这条性质又叫欧拉反演
证明:
定义函数 f(n)=i|nφ(i)
f(n) 是积性函数,证明: f(n)×f(m)=i|nφ(i)×j|mφ(j)=i|nj|mφ(i)φ(j)=i|nj|mφ(i×j)=d|nmφ(d)=f(nm)

f(pk)=φ(1)+φ(p)+φ(p2)++φ(pk)=1+(p1)+(p2p)++(pkpk1)=pk
n=p1k1×p2k2××pmkm
f(n)=f(p1k1)×f(p2k2)××pmkm=p1k1×p2k2××pmkm=n

求欧拉函数

求单个数的欧拉函数

直接根据之前的通式 φ(x)=xi=1n(11pi) 计算即可。
其中有以下几点细节:

  • 如果以 n 为上界分解质因数之后得到的值不是 1,说明 n 有一个大于 n 的质因数,要再进行一次计算。
  • 对于通项公式中 (11pi) 这一项,在代码实现中将其转化为 pi1pi
int phi(int x){
	int ans=x;
	for(int i=2;i*i<=x;i++)
		if(x%i==0){
			ans=ans/i*(i-1);
			while(x%i==0)x/=i;
		}
	if(x>1)ans=ans/x*(x-1);
	return ans;
}

预处理欧拉函数

以下用 pi 表示数字 i 的欧拉函数值,即 φ(i)

  • O(nlog2(log2n)) 的筛法:

基本上不会被卡,而且比较好写的筛法。
先把所有 pi 初始化为 i
对于当前枚举到的数 i,如果 pi=i,那么 i 为质数,并对之后包括 i 在内的的倍数进行更新。
更新就是根据上面的通项公式,对于 pj,就变为 pji1i

#define L(i,j,k) for(int i=(j);i<=(k);i++)
#define ll(i,j,k,l) for(int i=(j);i<=(k);i+=(l))
L(i,1,n) p[i]=i;
L(i,2,n) if(p[i]==i)
  ll(j,i,n,i) p[j]=p[j]/i*(i-1);
  • O(n) 的筛法:

预先规定:

  • si 表示筛出的第 i 个质数。
  • fi 表示数字 i 的最小质因数。

参考筛素数的线性筛,当筛到数字 i 时,小于 i 的数的欧拉函数和小于 i 的质数已经筛出,利用 is 向后更新。

对于数字 i,如果此时 fi=0,说明这个数的最小质因数不会在 [2,i1] 的范围内出现,也易得数字 i 是个质数,根据前一篇博客中写到的欧拉函数性质可知,此时 φ(i)=i1

所以,如果数字 i 为质数:

  1. i 加入筛出的素数表。
  2. fi=i,质数的最小质因数是自身。
  3. 更新 pi 的值为 i1

接下来,无论 i 是否为质数,直接在素数表中枚举 sj

  • 如果 imodsj!=0,可知 (i,sj)=1,此时有 pi×sj=pi×psj=pi×(sj1)
  • 如果 imodsj=0,此时 pi×sj=pi×sj
  • 同时更新 fsj×i=sj

证明:
imodsj=0 时无法直接计算的原因是两个数不互质。
假设 i×pj=A×pjm1×pj=pjm
x 是质数,φ(xk)=xkxk1
因为 φ(i×pj)=φ(A)×φ(pjm)=φ(A)×φ(pjm1)×p
其中 A×pjm1=i
所以 φ(A)×φ(pjm1)=φ(i)
联立得 φ(i×pj)=φ(A)×φ(pjm1)×p=φ(i)×pj
得证。
代码实现:

if(x==1)return 0;p[1]=1;
for(int i=2;i<n;i++){
    if(!f[i])s[++tp]=i,p[i]=i-1,f[i]=i;
    for(int j=1;j<=tp;j++){
	if(s[j]*i>n||s[j]>f[i])break;f[s[j]*i]=s[j];
	if(s[j]<f[i]) p[s[j]*i]=(s[j]-1)*p[i];
        else p[s[j]*i]=s[j]*p[i];
    }
}

欧拉定理

gcd(a,n)=1,则 aφ(n)1(modn)

证明:

从 1 到 n 中,与 n 互质的数为 φ(n) 个,将这些数放入集合 x 中,表示为 x1,x2,,xφ(n)
再另外设一个集合 m,其中的元素 m1=a×x1 m2=a×x2 mφ(n)=a×xφ(n)
接下来要证明两个推理。

  • 集合 m 中的任意两个数n 的余数不同,即不存在 ma,mb 满足 mamb(modn)

反证法证明。
假设存在 ma,mb 满足 mamb(modn),即 (mamb)÷n=k
所以 mamb=n×k
将集合 m 中的数用集合 x 中的数表示 a×xaa×xb=n×k
也就是 a×(xaxb)=n×k
因为已知 an 互质,所以式子转化为 (xaxb)modn=0
但是因为已知 xa,xb<n,即 xaxb<n
所以上述式子均不成立,得证。

  • 集合 m 的数除以 n 的余数都与 n互质。

首先已知 mi=a×xi
其次已知 an 互质,xin 互质,所以 mi 也就是 a×xin 互质。
所以带入欧几里得算法(辗转相除法)中推一步就行。

gcd(a×xi,n)=gcd(mi,n)=gcd(n,mimodn)=1

得证。

接下来开始推式子。
集合 m 中的每个元素分别对应集合 x 中的每个数同余。
因为第二个推理得到,m 集合中的每个元素模 n 的结果都与 n 互质,这与 x 中的数对应。
表示出来就是mixi(modn)
由此可得m1×m2××mφ(n)x1×x2××xφ(n)(modn)
把集合 m 中所有数都转换成集合 x 中的数乘以 a 的形式 aφ(n)×x1×x2××xφ(n)=x1×x2××xφ(n)(modn)
移项可得 (aφ(n)1)×x1×x2××xφ(n)0(modn)
因为上面式子中的x1,x2xφ(n) 均与 n 互质,所以相乘的结果也与 n 互质。
所以 aφ(n)10(modn)
aφ(n)1(modn)
Q.E.D

posted @   AIskeleton  阅读(222)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示