概念
欧拉函数 φ ( n ) φ(n) φ(n)描述的是小于等于n的正整数2中与n互质的个数。先回顾一下互质的定义,互质是指两个正整数的最大公约数为1。所以不难得出,1和任何正整数互质;除1外任何正整数和它自己不可能互质; n n n和 n + 1 n+1 n+1互质。另外,除 φ ( 1 ) = 1 φ(1)=1 φ(1)=1外,欧拉函数满足 φ ( n ) ≤ n − 1 φ(n)≤n-1 φ(n)≤n−1,当且仅当n是质数时等号成立。
比如 φ ( 12 ) = 4 φ(12)=4 φ(12)=4,1-12中和12互质的数包括1、5、7、11。
BTW,欧拉这个人也太恐怖了,图论里有欧拉公式 V + F − E = K V+F-E=K V+F−E=K,复变函数里有欧拉公式 c o s θ + i s i n θ = e i θ cos\theta+isin\theta=e^{i\theta} cosθ+isinθ=eiθ,数论里有欧拉函数、欧拉同余定理和欧拉线性筛,级数里有欧拉数,微分方程里有欧拉方程(欧拉方程还是少数有解析解的微分方程之一)。。。三百年不遇的一位奇才。
欧拉函数的公式
如果一个正整数n的质因子分解为
p
1
r
1
p
2
r
2
.
.
.
p
k
r
k
p_1^{r_1}p_2^{r_2}...p_k^{r_k}
p1r1p2r2...pkrk,则
φ
(
n
)
=
n
∏
i
=
1
k
(
1
−
1
p
i
)
φ(n)=n\prod_{i=1}^k(1-\frac{1}{p_i})
φ(n)=ni=1∏k(1−pi1)
下面来简单推导一下这个公式。我们知道,任何一个大于等于2的正整数都可以分解为质数的乘积的形式(质因子分解)。假设一个数
n
n
n分解为
p
1
r
1
p
2
r
2
.
.
.
p
k
r
k
p_1^{r_1}p_2^{r_2}...p_k^{r_k}
p1r1p2r2...pkrk,如果另一个正整数m和n互质,则没有任何相同的质因子。1-n这n个数中,能被质因子
p
1
p_1
p1整除的概率是
1
/
p
1
1/p_1
1/p1,能被
p
2
p_2
p2整除的概率是
1
/
p
2
1/p_2
1/p2,以此类推。又因为不同质因子的整除在概率上是相互独立的,由相互独立事件概率可知,不能被任何一个质因子整除的概率是
∏
i
=
1
k
(
1
−
1
p
i
)
(2)
\prod_{i=1}^k(1-\frac{1}{p_i})\tag{2}
i=1∏k(1−pi1)(2)
从而得到欧拉函数。
欧拉函数的计算
单个数的欧拉函数非常简单,分解质因子的同时可求出。1-n的所有数的欧拉函数可以用线性筛法,下面会讲。
int phi(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
int i, k = n, ans = n;
for (i = 2; i * i <= k; i++) {
if (n % i) continue;
ans /= i;
ans *= i - 1;
while (n % i == 0) n /= i;
}
return n == k ? ans - 1 : ans;
}
时间复杂度 O ( n ) O(\sqrt n) O(n)。
欧拉函数的性质
1、乘法性质:如果 a , b a,b a,b互质,则 φ ( a b ) = φ ( a ) φ ( b ) φ(ab)=φ(a)φ(b) φ(ab)=φ(a)φ(b)。
推论1:如果 p p p为奇数,则 φ ( 2 p ) = φ ( p ) φ(2p)=φ(p) φ(2p)=φ(p);如果 p p p为偶数,则 φ ( 2 p ) = 2 φ ( p ) φ(2p)=2φ(p) φ(2p)=2φ(p)。
推论2:假设 p p p为质数。如果 q % p = 0 q\%p=0 q%p=0,则 φ ( p q ) = p ∗ φ ( q ) φ(pq)=p*φ(q) φ(pq)=p∗φ(q);如果 q % p ≠ 0 q\%p≠0 q%p=0,则 φ ( p q ) = ( p − 1 ) ∗ φ ( q ) φ(pq)=(p-1)*φ(q) φ(pq)=(p−1)∗φ(q)。根据此推论可以对线性筛法进行扩展,在 O ( n ) O(n) O(n)内求出1-n每个数的欧拉函数值。代码如下:
int eu[10000001];
int prime[1000000], cnt;
void euler(int n) {
int i, j;
eu[1] = 1;
for (i = 2; i <= n; i++) {
if (!eu[i]) {
prime[cnt++] = i;
eu[i] = i - 1;
}
for (j = 0; j < cnt && i * prime[j] <= n; j++) {
if (i % prime[j]) {
eu[i * prime[j]] = (prime[j] - 1) * eu[i];
} else {
eu[i * prime[j]] = prime[j] * eu[i];
break;
}
}
}
}
2、欧拉同余定理:对于两个互质的正整数 a , m a,m a,m,满足 a φ ( m ) % m = 1 a^{φ(m)}\ \%\ m=1 aφ(m) % m=1。特别地,如果m是质数,且 a % m ≠ 0 a\%m≠0 a%m=0,则是费马小定理 a m − 1 % m = 1 a^{m-1}\ \%\ m=1 am−1 % m=1。