欧拉函数(学习笔记)
欧拉函数:,
为
的质因数。
.
每种质因数只有一个。
性质:
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;
} 
京公网安备 11010502036488号