定义:对于正整数 n,欧拉函数是小于等于 n的数中与 n互质的数的个数。
符号: φ(n)表示 n的欧拉函数,默认 φ(1)=1。
一些定理:
1.对于一个素数 p, φ(p)=p−1。
证明略。
2.对于两个互质的数 a,b, φ(a×b)=φ(a)×φ(b)。 (感谢 hyj 巨佬的指正 )
证明:因为 a与 b互质,所以 a与 b没有共同的质因数。设 a有 ka个质因数, b有 kb个质因数,因此:
φ(a)∗φ(b)=a∗i=1∏ka(1−p[i]1)∗b∗i=1∏kb(1−p[i]1)=a∗b∗i=1∏ka+kb(1−p[i]1)=φ(a∗b)
注:欧拉函数是积性函数,但不是完全积性函数。
update:这个证法貌似是错的,因为要用到欧拉函数的公式,但是欧拉函数的公式又要由这个式子推出来。所以只能显然正确了。真的证明我还不会 (我菜爆了 ),可以参考这里
3.对于一个素数 p的幂次,如 pa,有 φ(pa) = (p−1) × pa−1。
证明:比 pa小的正整数共 pa−1个。其中所有 p的倍数可以表示成 p × t (t=1,2......pa−1−1),即共有 pa−1−1个数能被 p整除。因为 p是质数,所以显然只有这些数不能被 p整除,剩余的数都与 p互质。因此, φ(pa) = pa−1 − (pa−1−1) = (p−1) × pa−1。
4.如果 i%p=0,那么 φ(i×p)=φ(i)×p。
证明:懒了不想写,好像没多大用。
求欧拉函数:
1.求单个欧拉函数: φ(x) =x × i=1∏k(1−p[i]1)
其中 p[1],p[2]......p[k]为 x的所有质因子
证明:首先,由整数的唯一分解定理可得, x = p[1]a1 × p[2]a2 × ...... × p[k]ak。显然 p[1]a1, p[2]a2, ......, p[k]ak之间两两互质。那么,根据定理 2,3:
φ(x)=φ(p[1]a1)∗φ(p[2]a2)∗......∗φ(p[k]ak)=(p[1]a1∗(1−p[1]1))∗(p[2]a2∗(1−p[2]1))∗......∗(p[k]ak∗(1−p[k]1))=(p[1]a1∗p[2]a2∗......∗p[k]ak)∗(1−p[1]1)∗(1−p[2]1)∗......∗(1−p[k]1)=x∗i=1∏k(1−p[i]1)
代码:
inline int getphi(int x){
int res=x;
for(int i=2;i*i<=x;i++){
if(x%i==0){
res=res/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) res=res/x*(x-1);
return res;
}
2.线性筛欧拉函数:方法类似于筛素数,其实并不难,在筛素数的同时进行筛欧拉函数。
用到上面的1,2,4定理。
代码:
for(int i=2;i<=n;i++){
if(!v[i]){
phi[i]=i-1;
pr[++top]=i;
}
for(int j=1;j<=top&&i*pr[j]<=n;j++){
v[i*pr[j]]=1;
if(i%pr[j]==0){
phi[i*pr[j]]=phi[i]*pr[j];
break;
}
else phi[i*pr[j]]=phi[i]*phi[pr[j]];
}
}
欧拉定理:若 gcd(a,m)=1,那么 aφ(m) ≡ 1(modm)。
证明:找欧拉去