[编程笔记]-Euler's_Totient_Function欧拉函数

概念

φ(n)表示1~n之中与n互质的数的个数

令N=P1α1*P2α2*P3α3*…*Pkαk

则φ(N)=N(1-1/P1)(1-1/P2)(1-1/P3)…(1-1/Pk)

推导

  1. 求出N的质因数
  2. 从1~N中去掉P1,P2到Pk的倍数。
  3. 加上所有Pi*Pj的倍数,因为第二步把它们多减了一次。
  4. 减去所有Pi*Pj*Pk的倍数,因为第三步把它们多加了一次……

手搓示意图1

手搓示意图2

可得:

容斥原理
N-N/P1-N/P2-N/P3-…-N/Pk
+N/P1P2+N/P1P3+…+N/Pk-1Pk
-N/P1P2P3-…-N/Pk-2Pk-1Pk
+…
归纳得:

φ(N)=N(1-1/P1)(1-1/P2)(1-1/P3)…(1-1/Pk)

代码

朴素做法

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
#include<bits/stdc++.h>
using namespace std;

const int N=105;

int res;
int n,a;
int prime[N];

int main(){
cin.tie(0);
cin>>n;
while(n--){
cin>>a;
int res=a;
for(int i=2;i<=a/i;i++){
if(a%i==0){
res=res/i*(i-1);
while(a%i==0)a/=i;
}
}
if(a>1)res=res/a*(a-1);
cout<<res<<endl;
}
return 0;
}

线性筛法

前言

要是不会线性筛,就请先学一下先:
[编程笔记]-Prime_Basis质数基础

原理

特殊但不是很特殊地,φ(1)=1,因为1本身也与1互质。

当x为质数时,φ(x)=x-1

对于每个x=Pj*i:

  1. 若i%Pj==0,那么Pj就是i的最小质因子,因此x的质因子就是i的质因子。所以,φ(x)=Pj*φ(i)。(详细:由于质因子相同,所以两个欧拉函数除了开头”N”部分都一样,而x也就是Pj*i,所以就是Pj*i*[函数后部分],即Pj*φ(i))
  2. 若i%Pj!=0,那么Pj就不是i的质因子,但是i*Pj的最小质因子。因为Pj是质数,所以它的质因子只有它本身。φ(Pj*i)=Pj*i*[i的欧拉函数剩余部分]*(1-1/Pj),也就等同于φ(Pj)*φ(i),或者是(Pj-1)*φ(i)。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int n, phi[N];

void euler(){
int cnt=0;
int prime[N];
bool st[N]={false};
phi[1]=1;
for(int i=2;i<=n;i++){
if(!st[i]){
prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;prime[j]<=n/i;j++){
st[prime[j]*i]=true;
if(i%prime[j]==0){
phi[prime[j]*i]=prime[j]*phi[i];
break;
}
phi[prime[j]*i]=phi[prime[j]]*phi[i];
}
}
}

欧拉定理

定理

若a与n互质,aφ(n)≡1(mod n)

证明

若在1~n中,所有与n互质的数为a1, a2, …aφ(n)

又因a与n互质,

所以a*a1, a*a2, …a*aφ(n) 都满足≡1(mod n)

并且在这个序列里,产生的数两两各不相同。

证明如下:

反证法,若a*ai≡a*aj(mod n)
则a(ai-aj)≡0(mod n)
因a与n互质,可得:
ai-aj≡0(mod n)
ai≡aj(mod n)
但ai, aj都是n的不同的质因数,因此不成立。

因此,新序列也是φ(n)个互不相同且与n互质的数。

那么就可以得到(毕竟与n互质的数只有φ(n)个):前后两个序列,内部元素(mod n后)其实是一样的,就是顺序可能会有所不同,所以它们乘积也应该同余。

那么易得:

aφ(n)(a1*…*aφ(n))≡a1*…*aφ(n)(mod n)

又因ai都是n的质因数,所以,(a1*…*aφ(n))也就是n的质因数。

所以aφ(n)≡1(mod n)

别忘了a与n互质。

简单推论——费马小定理

当n为质数时,aφ(p)≡1(mod p)

则,ap-1≡1(mod p)

别忘了a与p互质。

没错这就是费马小定理

完结撒花o( ̄︶ ̄)o


[编程笔记]-Euler's_Totient_Function欧拉函数
http://githarlem.github.io/2024/08/05/Eulers-Totient-Function/
作者
Harlem
发布于
2024年8月5日
更新于
2024年8月6日
许可协议