【4.3 欧拉函数详解】

更 好 的 阅 读 体 验 \color{red}{更好的阅读体验}


概念

  • 1 ∼ N 1∼N 1N中与 N N N互质的数的个数被称为欧拉函数,记为 ϕ ( N ) \phi(N) ϕ(N),特别的 ϕ ( 1 ) = 1 \phi(1)=1 ϕ(1)=1
  • 欧拉函数是一个积性函数,若 m m m n n n互质,则有 ϕ ( m × n ) = ϕ ( m ) × ϕ ( n ) \phi(m\times n)=\phi(m)\times\phi(n) ϕ(m×n)=ϕ(m)×ϕ(n)

4.3.1 公式法求欧拉函数

思想

  • 算术基本定理:任何一个大于 1 1 1的自然数 N N N,如果 N N N不为质数

  • 那么 N N N可以唯一分解成有限个质数的乘积 N = p 1 a 1 × p 2 a 2 ⋯ × p i a k N=p_1^{a_1}\times p_2^{a_2}\dots\times p_i^{a_k} N=p1a1×p2a2×piak,且最多只有一个大于 n \sqrt{n} n 的质因子

  • 这里 p 1 < p 2 < p 3 … p i p_1<p_2<p_3\dots p_i p1<p2<p3pi均为质数,其中指数 a k a_k ak是正整数

  • ϕ ( N ) = ϕ ( p 1 a 1 ) × ϕ ( p 2 a 2 ) × ⋯ × ϕ ( p n a n ) \phi(N)=\phi(p_1^{a_1})\times\phi(p_2^{a_2})\times\dots\times\phi(p_n^{a_n}) ϕ(N)=ϕ(p1a1)×ϕ(p2a2)××ϕ(pnan)

  • 对于任意一项 ϕ ( p i a i ) \phi(p_i^{a_i}) ϕ(piai),与 p i a i p_i^{a_i} piai不互质的数有 p i , 2 × p i , 3 × p i , … , p i ( a i − 1 ) × p i p_i,2\times p_i,3\times p_i,\dots,p_i^{(a_i-1)}\times p_i pi,2×pi,3×pi,,pi(ai1)×pi p i ( a i − 1 ) p_i^{(a_i-1)} pi(ai1)

  • ϕ ( p i a i ) = p i a i − p i ( a i − 1 ) \phi(p_i^{a_i})=p_i^{a_i}-p_i^{(a_i-1)} ϕ(piai)=piaipi(ai1)

  • ϕ ( N ) = ϕ ( p 1 a 1 ) × ϕ ( p 2 a 2 ) × ⋯ × ϕ ( p n a n ) = ( p 1 a 1 − p 1 ( a 1 − 1 ) ) × ( p 2 a 2 − p 2 ( a 2 − 1 ) ) × ⋯ × ( p n a n − p n ( a n − 1 ) ) = p 1 a 1 × p 2 a 2 × ⋯ × p n a n × ( 1 − 1 p 1 ) × ( 1 − 1 p 2 ) × ⋯ × ( 1 − 1 p n ) = N × ∏ i = 1 n ( 1 − 1 p i ) \begin{aligned} \phi(N)&=\phi(p_1^{a_1})\times\phi(p_2^{a_2})\times\dots\times\phi(p_n^{a_n})\\ &=(p_1^{a_1}-p_1^{(a_1-1)})\times(p_2^{a_2}-p_2^{(a_2-1)})\times\dots\times(p_n^{a_n}-p_n^{(a_n-1)})\\ &=p_1^{a_1}\times p_2^{a_2}\times\dots\times p_n^{a_n}\times(1-\frac{1}{p_1})\times(1-\frac{1}{p_2})\times\dots\times(1-\frac{1}{p_n})\\ &=N\times\prod^{n}_{i=1}{(1-\frac{1}{p_i})} \end{aligned} ϕ(N)=ϕ(p1a1)×ϕ(p2a2)××ϕ(pnan)=(p1a1p1(a11))×(p2a2p2(a21))××(pnanpn(an1))=p1a1×p2a2××pnan×(1p11)×(1p21)××(1pn1)=N×i=1n(1pi1)

模板

typedef long long LL;

LL phi(LL n){
    
    LL res=n;
    
    for(int i=2;i<=n/i;i++){
        
        if(n%i==0){
            res=res/i*(i-1);  //(1-1/i)转换为(i-1)/i
            while(n%i==0) n/=i;
        }
        
    }
    
    if(n>1) res=res/n*(n-1);
    
    return res;
    
}

例题 873. 欧拉函数

原题链接

描述

给定 n 个正整数 ai,请你求出每个数的欧拉函数。

欧拉函数的定义
1∼N 中与 N 互质的数的个数被称为欧拉函数,记为 ϕ(N)。
若在算数基本定理中,N=pa11pa22…pamm,则:
ϕ(N) = N×p1−1p1×p2−1p2×…×pm−1pm

输入格式
第一行包含整数 n。

接下来 n 行,每行包含一个正整数 ai。

输出格式
输出共 n 行,每行输出一个正整数 ai 的欧拉函数。

数据范围
1≤n≤100,
1≤ai≤2×109
输入样例:

3
3
6
8

输出样例:

2
2
4

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

LL phi(LL n){
    
    LL res=n;
    
    for(int i=2;i<=n/i;i++){
        
        if(n%i==0){
            res=res/i*(i-1);
            while(n%i==0) n/=i;
        }
        
    }
    
    if(n>1) res=res/n*(n-1);
    
    return res;
    
}

int main(){
    
    int n;
    
    cin>>n;
    
    while(n--){
        
        int x;
        
        cin>>x;
        
        cout<<phi(x)<<endl;
        
    }
    
    return 0;
    
}

4.3.2 筛法求欧拉函数

思想

  • 利用线性筛,在筛选 1 ∼ N 1\sim N 1N中的质数时,将 1 ∼ N 1\sim N 1N的欧拉函数 ϕ ( P i ) \phi(P_i) ϕ(Pi)求出
  • 对于质数 P i P_i Pi,其 ϕ ( P i ) = P × ( 1 − 1 P ) = P − 1 \phi(P_i)=P\times(1-\frac{1}{P})=P-1 ϕ(Pi)=P×(1P1)=P1
  • 对于合数 P i P_i Pi,其 ϕ ( P i ) = N × ∏ i = 1 n ( 1 − 1 p i ) \phi(P_i)=N\times\prod^{n}_{i=1}{(1-\frac{1}{p_i})} ϕ(Pi)=N×i=1n(1pi1)
  • 在线性筛法求质数的模板中利用最小质因子筛掉合数的过程时:
    • i % p r i m e s [ j ] = 0 i\%primes[j]=0 i%primes[j]=0时,说明 p r i m e s [ j ] primes[j] primes[j] i i i的一个质因子,且 p r i m e s [ j ] primes[j] primes[j] p r i m e s [ j ] × i primes[j]\times i primes[j]×i的一个质因子,故 ϕ ( i ) \phi(i) ϕ(i)包含 ( 1 − 1 p r i m e s [ j ] ) (1-\frac{1}{primes[j]}) (1primes[j]1)的情况,即 ϕ ( p r i m e s [ j ] × i ) = p r i m e s [ j ] × ϕ ( i ) \phi(primes[j]\times i)=primes[j]\times\phi(i) ϕ(primes[j]×i)=primes[j]×ϕ(i)
    • i % p r i m e s [ j ] ≠ 0 i\%primes[j]\ne 0 i%primes[j]=0时 ,说明 p r i m e s [ j ] primes[j] primes[j] i i i的最小质因子,且 p r i m e s [ j ] primes[j] primes[j]不是 p r i m e s [ j ] × i primes[j]\times i primes[j]×i的一个质因子,故 ϕ ( i ) \phi(i) ϕ(i)不包含 ( 1 − 1 p r i m e s [ j ] ) (1-\frac{1}{primes[j]}) (1primes[j]1)的情况,即 ϕ ( p r i m e s [ j ] × i ) = p r i m e s [ j ] × ϕ ( i ) × ( 1 − 1 p r i m e s [ j ] ) = ( p r i m e s [ j ] − 1 ) × ϕ ( i ) \begin{aligned}\phi(primes[j]\times i)&=primes[j]\times\phi(i)\times(1-\frac{1}{primes[j]})\\ &=(primes[j]-1)\times\phi(i)\end{aligned} ϕ(primes[j]×i)=primes[j]×ϕ(i)×(1primes[j]1)=(primes[j]1)×ϕ(i)

模板

int primes[N];   //存储当前筛选出的质数

bool vis[N];  //标记是否被筛掉

int phi[N]; //记录欧拉函数的值

int cnt;  //记录质数个数

void get_phi(int n){
    
    phi[1]=1;  //特别的,phi[1]=1
    
    for(int i=2;i<=n;i++){
        
        if(!vis[i]){
            primes[cnt++]=i;  //没有被筛掉说明是质数,记录到primes[N]中
            phi[i]=i-1;  //质数的欧拉函数的情况
        }
        
        for(int j=0;primes[j]<=n/i;j++){  //将1~n范围内质数primes[j]的i倍的合数筛掉
            
            vis[primes[j]*i]=1;
            if(i%primes[j]==0){  //用最小质因子primes[j]筛掉合数
                phi[primes[j]*i]=primes[j]*phi[i];  //包含(1-1/primes[j])的情况
                break;
            }
            else phi[primes[j]*i]=(primes[j]-1)*phi[i];  //不包含(1-1/primes[j])的情况
            
        }
        
    }
    
}

例题 874. 筛法求欧拉函数

原题链接

描述

给定一个正整数 n,求 1∼n 中每个数的欧拉函数之和。

输入格式
共一行,包含一个整数 n。

输出格式
共一行,包含一个整数,表示 1∼n 中每个数的欧拉函数之和。

数据范围
1≤n≤106
输入样例:

6

输出样例:

12

代码

#include <bits/stdc++.h>
using namespace std;

const int N=1e6+3;

typedef long long LL;

int primes[N];

bool vis[N];

int phi[N];

int cnt;

void get_phi(int n){
    
    phi[1]=1;
    
    for(int i=2;i<=n;i++){
        
        if(!vis[i]){
            primes[cnt++]=i;
            phi[i]=i-1;
        }
        
        for(int j=0;primes[j]<=n/i;j++){
            
            vis[primes[j]*i]=1;
            if(i%primes[j]==0){
                phi[primes[j]*i]=primes[j]*phi[i];
                break;
            }
            else phi[primes[j]*i]=(primes[j]-1)*phi[i];
            
        }
        
    }
    
}

int main(){
    
    int n;
    
    cin>>n;
    
    get_phi(n);
    
    LL res=0;
    
    for(int i=1;i<=n;i++){
        res+=phi[i];
    }
    
    cout<<res<<endl;
    
    return 0;
    
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪漫主义狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值