欧拉函数(学习笔记)

欧拉函数:,的质因数。

. 每种质因数只有一个。

性质:

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;
}