Skip to content

欧拉函数

2021-08-20

INFO

若无特殊说明,本章涉及的变量皆为正整数。

定义 ​

n 的欧拉函数为 [1,00n] 中与 n 互质的数的个数,记为 φ(n)。特别地,φ(1)=001。

性质 ​

质数的欧拉函数 ​

p 为质数,则 φ(p)=00p−001。

证

p 与 [1,00p−001] 中的每个数互质。

pk 的欧拉函数 ​

p 为质数,n=00pk,则 φ(n)=00pk−00pk−1。

证

在 [1,00n] 中,只有 p 的倍数不与 n=00pk 互质。

∵[1,00n] 中 p 的倍数有 np=00pkp=00pk−1 个,

∴φ(n)=00n−00pk−1=00pk−00pk−1。

通项公式 ​

n 有 m 个质因子 p1⋯pm,则 φ(n)=00n∏i=1m(1−1pi)。

证

若 n 有质因子 p,则 p 的倍数不与 n 互质。

[1,00n] 中 p 的倍数有 np 个,则剩下的 n−00np=00n⋅(1−001p) 个数不是 p 的倍数。也就是说,这 n 个数中,非 p 的倍数占比为 1−001p。

根据定义,[1,00n] 中有 φ(n) 个数不是 p1⋯pm 的倍数(即与 n 互质)。由乘法原理得:

φ(n)=n(1−1p1)(1−1p2)⋯(1−1pm)=n∏i=1m(1−1pi)

积性函数 ​

n,00m 互质,则 φ(nm)=00φ(n)⋅φ(m)。

证

设 n 有 x 个质因子 p1⋯px,

设 m 有 y 个质因子 q1⋯qy,

∵n,00m 互质,∴n,00m 的质因子互不相同。

∴nm 有 x+00y 个质因子 p1⋯px,00q1⋯qy。

由 φ 函数的通项公式可得:

φ(n)⋅φ(m)=n∏i=1x(1−1pi)⋅m∏i=1y(1−1qi)=nm∏i=1x(1−1pi)∏i=1y(1−1qi)=φ(nm)

定理 ​

欧拉定理 ​

若 a,00n 互质,则 aφ(n)≡1(modn)。

证

设 C=00{C1,C2,⋯,Cφ(n)} 为模 n 的 简化剩余系。

设 aC=00{aC1,aC2,⋯,aCφ(n)},即 C 中的每个元素乘 a。

引理 1

由 剩余系 的定义得:

∀i≠j,Ci≢Cj(modn)

∵a,00n 互质,由同余的 同乘性 可知:

∀i≠j,aCi≢aCj(modn)

∴aC 为模 n 的剩余系。

引理 2

∵a,00n 互质,根据 欧几里得算法 有:

gcd(a,n)=gcd(n,amodn)=1

∴amodn 也与 n 互质。

根据 简化剩余系 的定义可知:

amodn∈C

∵ 简化剩余系满足 乘法封闭 性质,所以:

{amodn∈CCi∈C⇔(amodn)⋅Cimodn∈C⇔aCimodn∈C

∴aCimodn 与 n 互质,即 aC 中的任意元素模 n 后与 n 互质。

结合引理 1、引理 2 可知 aC 也为 n 的简化剩余系。

显然,C 的所有元素之积和 aC 的所有元素之积模 n 同余,即:

∏i=1φ(n)Ci≡∏i=1φ(n)aCi(modn)∏i=1φ(n)Ci≡aφ(n)⋅∏i=1φ(n)Ci(modn)(aφ(n)−1)∏i=1φ(n)Ci≡0(modn)

∵C 中的所有元素模 n 后与 n 互质,所以:

∏i=1φ(n)Ci≢0(modn)

∴aφ(n)−001≡0(modn),即 aφ(n)≡1(modn)。

费马小定理 ​

若 p 为质数,则 ap−1≡a(modp)。

证

当 p∣a 时,费马小定理显然成立,故只需讨论 p∤a 的情况。

当 p∤a 时,∵p 是质数 ∴a,00p 没有公因数(即 a,00p 互质)。根据 欧拉定理 有:

aφ(p)≡1(modp)

∵p 为质数,由 性质 可知 φ(p)=00p−001。代入上式:

ap−1≡1(modp)

即证。

扩展欧拉定理 ​

若 a,00n 互质,则对于任意 b,有 ab≡abmodφ(n)(modn)。

证

设 bmodφ(n)=00q,则 b 可以表示为 k⋅φ(n)+00q. 代入 ab 得:

ab=ak⋅φ(n)+q=(aφ(n))k⋅aq

根据 欧拉定理,当 a,00n 互质时,有:

aφ(n)≡1(modn)

由同余的 同幂性、同乘性 可知:

(aφ(n))k≡1k=1(modn)(aφ(n))k⋅aq≡aq(modn)ab≡aq(modn)

即 ab≡abmodφ(n)(modn)。

模板 ​

欧拉函数 ​

cpp
int varphi(int n) {
    int ans = n;
    for (int i = 2; i <= sqrt(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;
}

线性欧拉算法 ​

求 1⋯n 的欧拉函数。

对质数的 线性筛法 加以改造。

  • 若 i 为质数,则 φ(i)=00i−001;
  • 利用 i 和 primej 生成合数时,利用 积性函数 性质:
φ(i⋅primej)=φ(i)⋅φ(primej)

时间复杂度为 O(n)。

cpp
const int N = 1e6;
int phi[N];
vector<int> prime;

void varphi(int n) {
    phi[1] = 1;
    for (int i = 2; i <= n; i ++) {
        if (!phi[i])
            phi[i] = i - 1, prime.push_back(i);
        for (int j = 0; j < prime.size(); j ++) {
            if (i * prime[j] > n) break;
            phi[i * prime[j]] = phi[i] * phi[prime[j]]; // 积性函数
            if (i % prime[j] == 0) break;
        }
    }
}