欧拉函数 笔记

看着书上的定理,自己亲手证明。

定义

a,bN\forall a, b \in \mathbb{N},若 gcd(a,b)=1\gcd(a, b) = 1,则称 a,ba, b 互质。

定义 11nn 中与 nn 互质的数的个数为欧拉函数,记作 φ(n)\varphi(n)

计算式

若在唯一分解定理中,n=p1c1p2c2pmcmn = p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m},则 φ(n)=ni=1m(11pi)\varphi(n) = n\prod_{i=1}^m(1-\frac1{p_i}),证明如下:

从最简单的开始。设 p, q 都是 n 的因子,那么 n 以内 p, q 的倍数有 n / p, n / q 个,它们的公倍数有 n / pq 个。根据容斥原理,公倍数被算了两次,要减去一次。推广可得(iji \ne j):

φ(n)=nnpi+npipj+(1)mnp1p2pn=n[11pi+1pipj+(1)m1p1p2pm]=ni=1m(11pi)\begin{aligned} \varphi(n) &= n - \sum\frac{n}{p_i} + \sum\frac{n}{p_ip_j} - \cdots + (-1)^m\sum\frac{n}{p_1p_2\cdots p_n} \\ &= n[1-\sum\frac{1}{p_i}+\sum\frac{1}{p_ip_j} - \cdots + (-1)^m\sum\frac{1}{p_1p_2\cdots p_m}] \\ &= n\prod_{i=1}^m(1-\frac1{p_i}) \end{aligned}

性质

书上六条性质,我改成了四条。

性质1

n>1\forall n > 11n1 \sim n 中与 nn 互质的数的和为 nφ(n)2\frac{n\varphi(n)}{2}

证明:

1n1 \sim n 中与 nn 互质的数的和为 SS

由更相减损术得:

gcd(n,x)=gcd(n,nx)\gcd(n, x) = \gcd(n, n - x)

所以不与 n 互质的数成对出现(包括 00),且它们的平均值为 n/2n / 2

所以:

12n(n+1)Snφ(n)+1=n2n2+n2S=n2nφ(n)+n2S=nφ(n)2S=nφ(n)2\begin{aligned} \frac{\frac12 n(n+1) - S}{n - \varphi(n) + 1} &= \frac{n}{2} \\ \frac{n^2+n}{2} - S &= \frac{n^2 - n\varphi(n) + n}{2} \\ -S &= \frac{-n\varphi(n)}{2} \\ S &= \frac{n\varphi(n)}{2} \end{aligned}

性质2

gcd(a,b)=1\gcd(a, b) = 1,则 φ(ab)=φ(a)φ(b)\varphi(ab) = \varphi(a)\varphi(b)

证明:

a=i=1mpicia = \prod_{i=1}^m p_i^{c_i}b=i=m+1m+npicib = \prod_{i=m+1}^{m+n} p_i^{c_i},则 ab=i=1m+npiciab = \prod_{i=1}^{m+n}p_i^{c_i}

φ(a)=ai=1n(11pi)\varphi(a) = a\prod_{i=1}^n(1-\frac{1}{p_i})φ(b)=bi=m+1m+n(11pi)\varphi(b) = b\prod_{i=m+1}^{m+n}(1-\frac{1}{p_i})φ(ab)=abi=1m+n(11pi)\varphi(ab) = ab\prod_{i=1}^{m+n}(1-\frac{1}{p_i})

φ(a)φ(b)=ai=1n(11pi)×bi=m+1m+n(11pi)=abi=1m+n(11pi)\varphi(a)\varphi(b) = a\prod_{i=1}^n(1-\frac{1}{p_i}) \times b\prod_{i=m+1}^{m+n}(1-\frac{1}{p_i}) = ab\prod_{i=1}^{m+n}(1-\frac{1}{p_i})

所以 φ(ab)=φ(a)φ(b)\varphi(ab) = \varphi(a)\varphi(b)

推广:

定义积性函数 f(x)f(x) 为满足当 gcd(a,b)=1\gcd(a, b) = 1 时,f(ab)=f(a)f(b)f(ab) = f(a)f(b) 的函数。

对于积性函数 f(x)f(x),显然有:

若在算术基本定理中 x=i=1mpicix = \prod_{i=1}^m p_i^{c_i},则 f(x)=i=1mf(pici)f(x) = \prod_{i=1}^m f(p_i^{c_i})

性质3

pp 为质数且 pnp \mid n,则有:

φ(n)={φ(n/p)pp2nφ(n/p)(p1)p2n\varphi(n) = \left\{ \begin{array}{ll} \varphi(n / p) \cdot p & p^2 \mid n \\ \varphi(n / p) \cdot (p-1) & p^2 \nmid n \end{array} \right.

证明:

p2np^2 \mid n,则 p(n/p)p \mid (n / p)。这意味着 nnn/pn / p 的质因数集合相同。那么:

φ(n)φ(n/p)=n(1pi)n/p(1pi)=nn/p=p\frac{\varphi(n)}{\varphi(n / p)} = \frac{n\prod (1 - p_i)}{n / p\prod (1-p_i)} = \frac{n}{n / p} = p

φ(n)=φ(n/p)p\varphi(n) = \varphi(n / p) \cdot p

p2np^2 \nmid ngcd(n/p,p)=1\gcd(n / p, p) = 1,根据性质2,有:

φ(n)=φ(n/p)φ(p)=φ(n/p)(p1)\varphi(n) = \varphi(n / p) \varphi(p) = \varphi(n / p) \cdot (p - 1)

性质4

dnφ(d)=n\sum_{d\mid n} \varphi(d) = n

证明:

f(x)=dxφ(d)f(x) = \sum_{d\mid x} \varphi(d)

gcd(n,m)=1\gcd(n,m) = 1,则 d1n,d2m\forall d_1 \mid n, d_2 \mid m,有 gcd(d1,d2)=1gcd(d_1, d_2) = 1d1d2nmd_1d_2 \mid nm,那么 φ(d1)φ(d2)=φ(d1d2)\varphi(d_1)\varphi(d_2) = \varphi(d_1d_2)。同时 nmnm 的约数集为 {d1d2}\{d_1d_2\}

所以:

d1nφ(d1)×d2mφ(d2)=dnmφ(d)\sum_{d_1 \mid n} \varphi(d_1) \times \sum_{d_2 \mid m} \varphi(d_2) = \sum_{d \mid nm} \varphi(d)

即:

f(n)f(m)=f(nm)f(n)f(m) = f(nm)

这意味着 f(x)f(x) 是一个积性函数。

pp 是质数,则:

f(pc)=φ(1)+φ(p)+φ(p2)++φ(pc)=1+(p1)+p(p1)++pc1(p1)=11+pp+p2+pc1+pc=pc\begin{aligned} f(p^c) &= \varphi(1) + \varphi(p) + \varphi(p^2) + \cdots + \varphi(p^c) \\ &= 1 + (p - 1) + p(p - 1) + \cdots + p^{c - 1}(p - 1) \\ &= 1 - 1 + p - p + p^2 + \cdots - p^{c-1} + p^c \\ &= p^c \end{aligned}

所以若 n=i=1mpicin = \prod_{i=1}^m p_i^{c_i},则:

dnφ(d)=f(n)=i=1mf(pici)=i1mpici=n\sum_{d\mid n} \varphi(d) = f(n) = \prod_{i=1}^mf(p_i^{c_i}) = \prod_{i-1}^mp_i^{c_i} = n

计算

(以下涉及一些简单的 C++ 代码和埃筛、线性筛的基础,如果不会,可以自己上网查找资料)

注:

  • 埃筛:Eratosthenes 筛法的简称。
  • 线性筛:又称欧拉筛。

计算单个数的欧拉函数

利用试除法和欧拉函数计算式可求 φ(n)\varphi(n),时间复杂度为 O(n)O(\sqrt n)。代码很简单,书上也有,不用另外写了。

计算 1 到 n 中所有数的欧拉函数

利用埃筛

根据计算式计算。

先来回顾埃筛板子:

void primes(int n) {
  memset(v, 0, sizeof(v));
  for (int i = 2; i <= n; ++i) {
    if (v[i]) continue;
    for (int j = i; j <= n / i; ++j)
      v[i * j] = 1;
  }
}

计算欧拉函数之前,可以先初始化 phi[i] = i

注意到第 6 行 i 是质数,i * ji 的倍数,那么 phi[i*j] = phi[i*j] / i * (i - 1)

修改后的代码如下:

void euler(int n) {
  for (int i = 2; i <= n; ++i)
    phi[i] = i;
  for (int i = 2; i <= n; ++i) {
    if (phi[i] != i) continue; // 直接判断欧拉函数有没被改变过
    phi[i] = i - 1;
    for (int j = 2; j <= n / i; ++j) // 算欧拉函数的话一定要从 2 开始
      phi[i*j] = phi[i*j] / i * (i - 1);
  }
}

埃筛的时间复杂度为 O(nlogn)O(n \log n),一般不够用。

利用线性筛

印象中,某大佬说过,线性筛天生就适合计算积性函数。e.g. φ(n)\varphi(n)μ(n)\mu(n)

原理:性质3

pp 为质数且 pnp \mid n,则有:

φ(n)={φ(n/p)pp2nφ(n/p)(p1)p2n\varphi(n) = \left\{ \begin{array}{ll} \varphi(n / p) \cdot p & p^2 \mid n \\ \varphi(n / p) \cdot (p-1) & p^2 \nmid n \end{array} \right.

等价于:

φ(np)={φ(n)ppnφ(n)(p1)pn\varphi(np) = \left\{ \begin{array}{ll} \varphi(n) \cdot p & p \mid n \\ \varphi(n) \cdot (p-1) & p \nmid n \end{array} \right.

在线性筛中,第一种情况意味着 p=v(n)p = v(n)。这里的 v(n)v(n) 指的是 nn 的最小质因数。

线性筛求欧拉函数代码:

void euler(int n) {
  for (int i = 2; i <= n; ++i) {
    if (!v[i]) prime[++m] = v[i] = i, phi[i] = i - 1;
    for (int j = 1; j <= m; ++j) {
      if (prime[j] > v[i] || prime[j] > n / i) break;
      int nxt = prime[j] * i;
      v[nxt] = prime[j];
      phi[nxt] = phi[i] * (v[i]==prime[j] ? prime[j] : prime[j]-1);
    }
  }
}

例题

这篇文章写不下了,另起一篇:

https://blog.nowcoder.net/n/edc43d04c64844c08f05485e10aa75fc