欧拉函数(学习笔记)
欧拉函数:,
为
的质因数。
.
每种质因数只有一个。
性质:
1.当
为质数。
证明:显然当为质数,
显然与
互质。
,当
互质。
[特别地:当为奇质数时,
]
证明:为积性函数,具体不详细证明。
3.当
为质数
的
次幂。
证明:显然的倍数都不与
互质,这样的数个数为
所以互质的个数为
当
互质,且
为
倍数。
证明:根据公式有:,显然
都为
的质因子。
所以可改写为
接下来就可以用欧拉筛实现求欧拉函数。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5; #define mst(a) memset(a,0,sizeof a) int is_prime[N],phi[N],p[N],cnt; void Euler(int n){ phi[1]=1;//初始化 for(int i=2;i<=n;i++) { if(!is_prime[i]) //如果是素数 { p[++cnt]=i; phi[i]=i-1;//性质1 } for(int j=1;j<=cnt&&p[j]*i<=n;j++) //筛合数 { is_prime[p[j]*i]=1; if(i%p[j]==0){ //如果不是互质 phi[p[j]*i]=phi[i]*p[j];//性质4 break; } else phi[p[j]*i]=phi[p[j]]*phi[i];//性质2 } } } int main(){ int n; scanf("%d",&n); Euler(n); for(int i=1;i<=n;i++) printf("phi(%d):%d\n",i,phi[i]); return 0; }
方法2,利用公式计算。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5; #define mst(a) memset(a,0,sizeof a) int phi(int n){ int ans=n; for(int i=2;i<=n;i++){ if(n%i==0){ ans=ans/i*(i-1); while(n%i==0) n/=i; } } if(n>1) ans=ans/n*(n-1); return ans; } int main(){ int n; while(~scanf("%d",&n)){ printf("%d\n",phi(n)); } return 0; }