欧拉phi函数—详解

定义

1 1 1~ N N N中与 N N N互质的数的个数叫欧拉函数,记为 φ ( N ) \varphi(N) φ(N)
N N N分解质因数 N = p 1 c 1 ∗ p 1 c 1 ∗ . . . ∗ p k c k N=p_1^{c_1}*p_1^{c_1}*...*p_k^{c_k} N=p1c1p1c1...pkck
则有 φ ( N ) = N ∗ ( 1 − 1 p 1 ) ∗ ( 1 − 1 p 2 ) ∗ . . . ∗ ( 1 − 1 p k ) \varphi(N)=N*(1-\frac{1}{p_1})*(1-\frac{1}{p_2})*...*(1-\frac{1}{p_k}) φ(N)=N(1p11)(1p21)...(1pk1)
特别的 φ ( 1 ) = 1 \varphi(1)=1 φ(1)=1


证明

首先显然 1 1 1~ N N N中与 N N N互质的数就是
1 − N 1-N 1N中不与 N N N含有相同质因子的数

那么先简单分析 N N N只有两个质因子的情况
假设 p , q p,q p,q N N N的质因子
那么 1 1 1~ N N N中p的倍数有 N p \frac{N}{p} pN个,q的倍数有 N q \frac{N}{q} qN
我们自然要筛掉这些数 N − N p − N q N-\frac{N}{p}-\frac{N}{q} NpNqN

但是注意到这里面 p ∗ q p*q pq的倍数被减了两次
根据容斥原理,当然还要加回来
N − N p − N q + N p q N-\frac{N}{p}-\frac{N}{q}+\frac{N}{pq} NpNqN+pqN

对这个式子稍作变换
N − N p − N q + N p q N-\frac{N}{p}-\frac{N}{q}+\frac{N}{pq} NpNqN+pqN
            ⇓ \ \ \ \ \ \ \ \ \ \ \ \Downarrow            
N ∗ ( 1 − 1 p − 1 q + 1 p q ) N*(1-\frac{1}{p}-\frac{1}{q}+\frac{1}{pq}) N(1p1q1+pq1)
            ⇓ \ \ \ \ \ \ \ \ \ \ \ \Downarrow            
N ∗ ( 1 − 1 p ) ∗ ( 1 − 1 q ) N*(1-\frac{1}{p})*(1-\frac{1}{q}) N(1p1)(1q1)
只有两个质因数的情况证毕
到这里再用数学归纳法就可以拓展出上述得式子了


实现

根据上述函数定义式
可以得到一个在分解质因数时同时求解单个欧拉函数的方法
时间复杂度为 O ( N ) O(\sqrt{N}) O(N )

int phi(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;
}

当然我们还可以有递推打表的计算
类似埃式筛法
每枚举到一个质数,就更新他的所有倍数的phi值
复杂度约为 O ( N l o g N ) O(NlogN) O(NlogN)

void euler(int n)
{
    for(int i=1;i<=n;++i) phi[i]=i;
    for(int i=2;i<=n;++i)
    {
        if(phi[i]==i)//发现一个质数
        for(int j=i;j<=n;j+=i)//处理("筛")他的倍数
        phi[j]=phi[j]/i*(i-1);
    }
}

既然有类似埃式筛的递推方法
那么自然也不会少了线性筛

利用线性筛递推求解phi需要用到欧拉函数的两个性质
1.若有 p ∣ N p\mid N pN,且满足 p 2 ∣ N p^2\mid N p2N,则 φ ( N ) = φ ( N / p ) ∗ p \varphi(N)=\varphi(N/p)*p φ(N)=φ(N/p)p
2.若有 p ∣ N p\mid N pN,且一定不满足 p 2 ∣ N p^2\mid N p2N,则 φ ( N ) = φ ( N / p ) ∗ ( p − 1 ) \varphi(N)=\varphi(N/p)*(p-1) φ(N)=φ(N/p)(p1)
这两条性质会在接下来给出证明

线性筛中每个合数n只会被他的最小质因子p筛一次
于是我们利用这点从 φ ( N / p ) \varphi(N/p) φ(N/p)递推到 φ ( N ) \varphi(N) φ(N)

复杂度为 O ( N ) O(N) O(N)

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

欧拉函数的性质

1. ∀ N > 1 \forall N>1 N>1 1 1 1~ N N N中与 N N N互质的数的和为 N ∗ φ ( N ) / 2 N*\varphi(N)/2 Nφ(N)/2

证明

若有 x ∈ [ 1 , N ] x\in[1,N] x[1,N] g c d ( N , x ) = 1 ( 即 N 与 x 互 质 ) gcd(N,x)=1(即N与x互质) gcd(N,x)=1Nx
根据更相减损术 g c d ( N , x ) = g c d ( N , N − x ) gcd(N,x)=gcd(N,N-x) gcd(N,x)=gcd(N,Nx)

1 1 1~ N N N中与 N N N互质的数是成对出现的,对称轴就是 N / 2 N/2 N/2
也就是说 1 1 1~ N N N中与 N N N互质的数的平均值 N / 2 N/2 N/2
而总和就是 N ∗ φ ( N ) / 2 N*\varphi(N)/2 Nφ(N)/2
证毕


2.(1)当 a , b a,b ab互质时,有 φ ( a ∗ b ) = φ ( a ) ∗ φ ( b ) \varphi(a*b)=\varphi(a)*\varphi(b) φ(ab)=φ(a)φ(b)
(2)对 N N N分解质因数 N = p 1 c 1 ∗ p 1 c 1 ∗ . . . ∗ p k c k N=p_1^{c_1}*p_1^{c_1}*...*p_k^{c_k} N=p1c1p1c1...pkck,则有 φ ( N ) = ∏ i = 1 k φ ( p i c i ) \varphi(N)=\prod_{i=1}^k\varphi(p_i^{c_i}) φ(N)=i=1kφ(pici)

证明

这里的两条性质其实是直接应用了积性函数的性质
什么是积性函数
如果当 a , b a,b ab互质时,有 f ( a ∗ b ) = f ( a ) ∗ f ( b ) f(a*b)=f(a)*f(b) f(ab)=f(a)f(b),则 f ( x ) 为 积 性 函 数 f(x)为积性函数 f(x)
上述(1)是直接应用了定义
而(2)中将N分解质因数,显然分解的每一项都两两互质
根据积性函数定义也不难得出上述式子


3.(1)若有 p ∣ N p\mid N pN,且满足 p 2 ∣ N p^2\mid N p2N,则 φ ( N ) = φ ( N / p ) ∗ p \varphi(N)=\varphi(N/p)*p φ(N)=φ(N/p)p
(2)若有 p ∣ N p\mid N pN,且一定不满足 p 2 ∣ N p^2\mid N p2N,则 φ ( N ) = φ ( N / p ) ∗ ( p − 1 ) \varphi(N)=\varphi(N/p)*(p-1) φ(N)=φ(N/p)(p1)

证明

上述(1)中"若有 p ∣ N p\mid N pN,且满足 p 2 ∣ N p^2\mid N p2N"
说明N和N/p含有相同质因子
我们分析只含有两个质因子p和q的简单情况
φ ( N ) = N − N p − N q + N p q \varphi(N)=N-\frac{N}{p}-\frac{N}{q}+\frac{N}{pq} φ(N)=NpNqN+pqN
φ ( N / p ) = N p − N p 2 − N p q + N p 2 q \varphi(N/p)=\frac{N}{p}-\frac{N}{p^2}-\frac{N}{pq}+\frac{N}{p^2q} φ(N/p)=pNp2NpqN+p2qN
二者相除商为p
用数学归纳法扩展出k个质因子的情况可以得到相同结果

上述(2)中 “若有 p ∣ N p\mid N pN,且一定不满足 p 2 ∣ N p^2\mid N p2N
说明 N N N N / p N/p N/p一定互质
根据积性函数定义有 φ ( N ) = φ ( N / p ) ∗ φ ( p ) \varphi(N)=\varphi(N/p)*\varphi(p) φ(N)=φ(N/p)φ(p)
因为p为素数,所以 φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p1
φ ( N ) = φ ( N / p ) ∗ ( p − 1 ) \varphi(N)=\varphi(N/p)*(p-1) φ(N)=φ(N/p)(p1)
证毕


4. ∑ d ∣ n φ ( d ) = n \sum_{d|n}\varphi(d)=n dnφ(d)=n

证明

f ( n ) = ∑ d ∣ n φ ( d ) = n f(n)=\sum_{d|n}\varphi(d)=n f(n)=dnφ(d)=n
若有n,m互质,那么 f ( n m ) = ∑ d ∣ n m φ ( d ) = ∑ d ∣ n φ ( d ) ∗ ∑ d ∣ m φ ( d ) f(nm)=\sum_{d|nm}\varphi(d)=\sum_{d|n}\varphi(d)*\sum_{d|m}\varphi(d) f(nm)=dnmφ(d)=dnφ(d)dmφ(d)
可得 f ( n ) f(n) f(n)积性函数

对于n的某个质因子 f ( p k ) = ∑ d ∣ p k φ ( d ) = φ ( 1 ) + φ ( p ) + φ ( p 2 ) + . . . + φ ( p k ) f(p^k)=\sum_{d|p^k}\varphi(d)=\varphi(1)+\varphi(p)+\varphi(p^2)+...+\varphi(p^k) f(pk)=dpkφ(d)=φ(1)+φ(p)+φ(p2)+...+φ(pk)
由上述3.(1)知该式为一个等比数列+1公比为p
更具等比数列求和公式得 f ( p k ) = p k f(p^k)=p^k f(pk)=pk

所以 f ( n ) = ∏ i = 1 k f ( p k ) = ∏ i = 1 k p k = n f(n)=\prod_{i=1}^{k}f(p^k)=\prod_{i=1}^kp^k=n f(n)=i=1kf(pk)=i=1kpk=n
证毕


欧拉定理

定理:若正整数 a , n a,n a,n互质,则有 a φ ( n ) ≡ 1 ( m o d    n ) a^{\varphi(n)}\equiv 1(\mod n) aφ(n)1(modn)

推论:若正整数 a , n a,n a,n互质,则对于任意正整数b,有 a b ≡ a b m o d    φ ( n ) ( m o d    n ) a^b\equiv a^{b\mod \varphi(n)}(\mod n) ababmodφ(n)(modn)

扩展欧拉定理:
a , n ∈ Z a,n\in Z a,nZ,则 a b a^b ab { a b , b < φ ( n ) a b m o d    φ ( n ) + φ ( n ) , b > = φ ( n ) \left\{\begin{aligned}a^b,b<\varphi(n)\\ a^{b\mod\varphi(n)+\varphi(n) },b>=\varphi(n)\end{aligned}\right. {ab,b<φ(n)abmodφ(n)+φ(n),b>=φ(n) m o d    n \mod n modn

证明略

应用

给定三个正整数 a , m , b a,m,b a,m,b,求 a b m o d    m a^b\mod m abmodm
1 ≤ a ≤ 1 0 9 , 1 ≤ b ≤ 1 0 20000000 , 1 ≤ m ≤ 1 0 6 1≤a≤10^{9},1≤b≤10^{20000000},1≤m≤10^6 1a109,1b1020000000,1m106

直接套用上述定理

#include<iostream>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;

const int maxn=100010;
lt a,m,phi,rem;

lt read()
{
    lt x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9') ss=getchar();
    while(ss>='0'&&ss<='9'){
        x=x*10+ss-'0';ss=getchar();
        if(x>=phi) rem=1,x%=phi;
    }
    return x;
}

lt calc(lt x)
{
    lt 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;
}

lt qpow(lt aa,lt k)
{
    lt res=1;
    while(k){
        if(k&1) res=(res*aa)%m;
        aa=(aa*aa)%m; k>>=1;
    }
    return res;
}

int main()
{
    scanf("%d%d",&a,&m);
    phi=calc(m);
    
    lt b=read();
    if(rem) b+=phi;
    
    printf("%d",qpow(a,b));
    return 0;
}
  • 15
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值