这是重新整理的欧拉函数,会把欧拉函数的一些性质说出来。
欧拉函数即
φ
(
i
)
\varphi(i)
φ(i),表示从
[
1
,
i
]
[1, i]
[1,i] 之间和
i
i
i 互质的数的数量 (
a
a
a 和
b
b
b 互质即
gcd
(
a
,
b
)
=
1
\gcd(a, b) = 1
gcd(a,b)=1)。
注意当
i
=
1
i=1
i=1 时,
φ
(
1
)
=
1
\varphi(1) = 1
φ(1)=1。
递推公式(积性)
欧拉函数有一个算是递推式的东西,即对于任意正整数
a
a
a:
φ
(
a
b
)
=
φ
(
a
)
×
φ
(
b
)
×
gcd
(
a
,
b
)
φ
(
gcd
(
a
,
b
)
)
φ(ab) = \frac {φ(a) \times φ(b) \times \gcd(a,b)}{φ(\gcd(a,b))}
φ(ab)=φ(gcd(a,b))φ(a)×φ(b)×gcd(a,b)
易得,当
a
,
b
a,b
a,b 互质时,有:
φ
(
a
b
)
=
φ
(
a
)
×
φ
(
b
)
\varphi(ab) = \varphi(a) \times\varphi(b)
φ(ab)=φ(a)×φ(b)
证明
利用计算公式证明,你可以直接把计算公式带进去直接化,设
d
=
gcd
(
a
,
b
)
d = \gcd(a,b)
d=gcd(a,b) 那么可得
φ
(
a
b
)
=
φ
(
a
)
×
φ
(
b
)
×
gcd
(
a
,
b
)
φ
(
gcd
(
a
,
b
)
)
=
a
∏
i
=
1
k
a
(
1
−
1
p
i
)
×
b
∏
i
=
1
k
b
(
1
−
1
p
i
)
×
d
d
∏
i
=
1
k
d
(
1
−
1
p
i
)
=
a
∏
i
=
1
k
a
(
1
−
1
p
i
)
×
b
∏
i
=
1
k
b
(
1
−
1
p
i
)
∏
i
=
1
k
d
(
1
−
1
p
i
)
\begin{aligned} φ(ab) &= \frac {φ(a) \times φ(b) \times \gcd(a,b)}{φ(\gcd(a,b))} \\ &= \frac{a\prod_{i=1}^{k_a} \left(1-\frac{1}{p_i}\right) \times b\prod_{i=1}^{k_b} \left(1-\frac{1}{p_i}\right) \times d} {d\prod_{i=1}^{k_d} \left(1-\frac{1}{p_i}\right)} \\ &= \frac{a\prod_{i=1}^{k_a} \left(1-\frac{1}{p_i}\right) \times b\prod_{i=1}^{k_b} \left(1-\frac{1}{p_i}\right)} {\prod_{i=1}^{k_d} \left(1-\frac{1}{p_i}\right)} \end{aligned}
φ(ab)=φ(gcd(a,b))φ(a)×φ(b)×gcd(a,b)=d∏i=1kd(1−pi1)a∏i=1ka(1−pi1)×b∏i=1kb(1−pi1)×d=∏i=1kd(1−pi1)a∏i=1ka(1−pi1)×b∏i=1kb(1−pi1)
因为 d 是
a
,
b
a,b
a,b 的最大公约数,那么分母上的
∏
i
=
1
k
d
(
1
−
d
p
i
)
\prod_{i=1}^{k_d} \left(1-\frac{d}{p_i}\right)
∏i=1kd(1−pid) 就可以把
a
∏
i
=
1
k
a
(
1
−
1
p
i
)
×
b
∏
i
=
1
k
b
(
1
−
1
p
i
)
a\prod_{i=1}^{k_a} \left(1-\frac{1}{p_i}\right) \times b\prod_{i=1}^{k_b} \left(1-\frac{1}{p_i}\right)
a∏i=1ka(1−pi1)×b∏i=1kb(1−pi1) 中
a
,
b
a,b
a,b 的
(
1
−
1
p
i
)
\left( 1 - \frac{1}{p_i} \right)
(1−pi1) 中相同的部分给消掉一个,剩下的就不重复,且乘起来就恰好就是
a
b
∏
i
=
1
k
a
b
(
1
−
1
p
i
)
ab\prod_{i=1}^{k_{ab}} \left(1-\frac{1}{p_i}\right)
ab∏i=1kab(1−pi1),也就是
φ
(
a
b
)
\varphi(ab)
φ(ab)。因为
a
,
b
a,b
a,b 含有
a
b
ab
ab 的所有质因子。
证毕。
这也就证明了欧拉函数是积性函数。
计算公式(通项式)
即:
φ
(
N
)
=
N
×
(
1
−
1
p
1
)
×
(
1
−
1
p
2
)
×
…
×
(
1
−
1
p
k
)
,
N
∈
Z
,
p
i
is prime
\varphi(N) = N \times (1 - \frac{1}{p_1}) \times (1 - \frac{1}{p_2}) \times \ldots \times (1 - \frac{1}{p_k}), \quad N \in \text Z, p_i \text{ is prime}
φ(N)=N×(1−p11)×(1−p21)×…×(1−pk1),N∈Z,pi is prime
利用积性证明
欧拉函数是积性函数,例如
a
,
b
a, b
a,b 都为正整数,有递推式为
φ
(
a
b
)
=
φ
(
a
)
×
φ
(
b
)
×
gcd
(
a
,
b
)
φ
(
gcd
(
a
,
b
)
)
φ(ab) = \frac {φ(a) \times φ(b) \times \gcd(a,b)}{φ(\gcd(a,b))}
φ(ab)=φ(gcd(a,b))φ(a)×φ(b)×gcd(a,b)
当
a
,
b
a,b
a,b 互质时,则有
φ
(
a
b
)
=
φ
(
a
)
×
φ
(
b
)
φ(ab) = φ(a) \times φ(b)
φ(ab)=φ(a)×φ(b)
下面开始证明
设一个正整数
N
N
N,把它分解成质数,可得
N
=
p
1
b
1
×
p
2
b
2
×
p
3
b
3
×
…
×
p
k
b
k
,
p
i
is prime
N = p_1^{b_1} \times p_{2}^{b_2} \times p_{3}^{b_3} \times \ldots \times p_{k}^{b_k} ,\quad p_i \text{ is prime}
N=p1b1×p2b2×p3b3×…×pkbk,pi is prime
又因为 当
a
,
b
a,b
a,b 互质时
φ ( a b ) = φ ( a ) × φ ( b ) , gcd ( a , b ) = 1 \varphi(ab) = \varphi(a) \times φ(b), \quad \gcd(a, b) = 1 φ(ab)=φ(a)×φ(b),gcd(a,b)=1
所以
φ
(
N
)
=
φ
(
p
1
b
1
)
×
φ
(
p
2
b
2
)
×
φ
(
p
3
b
3
)
×
…
×
φ
(
p
k
b
k
)
\varphi(N) = \varphi(p_1^{b_1}) \times \varphi(p_2^{b_2}) \times \varphi(p_3^{b_3}) \times \ldots \times \varphi(p_k^{b_k})
φ(N)=φ(p1b1)×φ(p2b2)×φ(p3b3)×…×φ(pkbk)
因为对于
φ
(
p
b
)
\varphi(p_b)
φ(pb) 来说,
[
1
,
p
b
]
[1, p^b]
[1,pb] 一共有
p
b
p^b
pb 个数。其中不与
p
b
p^b
pb 互质的数是
1
p
,
2
p
,
3
p
,
…
,
p
b
−
1
×
p
1p, 2p, 3p, \ldots, p^{b-1} \times p
1p,2p,3p,…,pb−1×p ,总共
p
b
−
1
p^{b-1}
pb−1 个,剩下的就是和
p
b
p_b
pb 互质的数,共
p
b
−
p
b
−
1
p^b - p^{b-1}
pb−pb−1 个数。
即
φ
(
p
b
)
=
p
b
×
(
1
−
1
p
)
φ(p^b) = p^b \times (1 - \frac{1}{p})
φ(pb)=pb×(1−p1)
因为
φ
(
N
)
=
φ
(
p
1
b
1
)
×
φ
(
p
2
b
2
)
×
φ
(
p
3
b
3
)
×
…
×
φ
(
p
k
b
k
)
φ
(
p
b
)
=
p
b
−
p
b
−
1
\varphi(N) = \varphi(p_1^{b_1}) \times \varphi(p_2^{b_2}) \times \varphi(p_3^{b_3}) \times \ldots \times \varphi(p_k^{b_k}) \\ \varphi(p^b) = p^b - p^{b-1}
φ(N)=φ(p1b1)×φ(p2b2)×φ(p3b3)×…×φ(pkbk)φ(pb)=pb−pb−1
可得
φ
(
N
)
=
p
1
b
1
(
1
−
1
p
1
)
×
p
2
b
2
(
1
−
1
p
2
)
×
…
×
p
k
b
k
(
1
−
1
p
k
)
\varphi(N) = p_1^{b_1} (1 - \frac{1}{p_1}) \times p_2^{b_2}(1 - \frac{1}{p_2}) \times \ldots \times p_k^{b_k}(1 - \frac{1}{p_k})
φ(N)=p1b1(1−p11)×p2b2(1−p21)×…×pkbk(1−pk1)
即
φ
(
N
)
=
(
p
1
b
1
×
p
2
b
2
×
…
×
p
k
b
k
)
×
(
1
−
1
p
1
)
(
1
−
1
p
2
)
…
(
1
−
1
p
k
)
\varphi(N) = (p_1^{b_1} \times p_2^{b_2} \times \ldots \times p_k^{b_k}) \times (1 - \frac{1}{p_1})(1 - \frac{1}{p_2}) \ldots (1 - \frac{1}{pk})
φ(N)=(p1b1×p2b2×…×pkbk)×(1−p11)(1−p21)…(1−pk1)
又因为
N
=
p
1
b
1
×
p
2
b
2
×
…
×
p
k
b
k
N = p_1^{b_1} \times p_2^{b_2} \times \ldots \times p_k^{b_k}
N=p1b1×p2b2×…×pkbk
可得
φ
(
N
)
=
N
×
(
1
−
1
p
1
)
×
(
1
−
1
p
2
)
×
…
×
(
1
−
1
p
k
)
\varphi(N) = N \times (1 - \frac{1}{p_1}) \times (1 - \frac{1}{p_2}) \times \ldots \times (1 - \frac{1}{p_k})
φ(N)=N×(1−p11)×(1−p21)×…×(1−pk1)
利用容斥定理
设一个正整数 N N N
由算数的基本定理得
N
=
p
1
b
1
×
p
2
b
2
×
p
3
b
3
×
…
×
p
k
b
k
,
p
i
is prime
N = p_1^{b_1} \times p_{2}^{b_2} \times p_{3}^{b_3} \times \ldots \times p_{k}^{b_k} ,\quad p_i \text{ is prime}
N=p1b1×p2b2×p3b3×…×pkbk,pi is prime
对于
φ
(
N
)
\varphi(N)
φ(N) 来说,求和
N
N
N 互质的数,也就是求和
N
N
N 不互质的数的数量。
那么对于分解出的一个质数
p
i
p_i
pi 来说,在
[
1
,
N
]
[1, N]
[1,N] 里面和它不互质的数就为
p
i
p_i
pi 的倍数,共
N
p
i
\frac{N}{p_i}
piN 个,但这个数量肯定要比和
N
N
N 不互质的数的数量多。我们可以画一个韦恩图来看。
我们要求和
N
N
N 不互质的数
m
m
m,那么
m
m
m 只需要和任意一个
p
i
p_i
pi 不互质即可,即上图的全集。
那么这就可以用容斥定理求出全集了。而这里的
p
i
p_i
pi 和
p
j
p_j
pj 的交集数量即为
N
p
i
p
j
\frac{N}{p_ip_j}
pipjN。
很容易可以得到
φ
(
N
)
=
N
−
(
∑
i
=
1
k
(
N
p
i
)
−
∑
i
=
1
k
∑
j
i
<
j
≤
k
(
N
p
i
p
j
)
+
…
)
\varphi(N) = N - (\sum_{i = 1}^{k}(\frac{N}{p_i}) - \sum_{i = 1}^{k} \sum_{j}^{i < j \le k}(\frac{N}{p_i p_j}) + \ldots )
φ(N)=N−(i=1∑k(piN)−i=1∑kj∑i<j≤k(pipjN)+…)
而这个式子可以化为
φ
(
N
)
=
N
×
(
1
−
1
p
1
)
×
(
1
−
1
p
2
)
×
…
×
(
1
−
1
p
k
)
\varphi(N) = N \times (1 - \frac{1}{p_1}) \times (1 - \frac{1}{p_2}) \times \ldots \times (1 - \frac{1}{p_k})
φ(N)=N×(1−p11)×(1−p21)×…×(1−pk1)
可以发现上面两个式子是等价的。可以这么理解,对于
(
1
−
1
p
i
)
(1 - \frac{1}{p_i})
(1−pi1) 来说,我们选取一个这个式子里的
−
1
p
i
-\frac{1}{p_i}
−pi1 其他的选
1
1
1,那么最后得出的就是
−
1
p
i
-\frac{1}{p_i}
−pi1,如果选两个
p
i
p_i
pi,其他的选
1
1
1,得出来的也就是
1
p
i
p
j
\frac{1}{p_ip_j}
pipj1 ,选三个
p
i
p_i
pi,其他选
1
1
1,得出的就是
−
1
p
i
p
j
p
k
-\frac{1}{p_ip_jp_k}
−pipjpk1,而这恰好就是容斥定理的进行形式。也就是说这两个是等价的
总结
于是就可以通过分解 N N N 的质因数求出来 φ ( N ) \varphi(N) φ(N),由此也可以看出,一个数的欧拉函数的大小和质数的次幂无关。
试除法分解质因数是
O
(
n
)
O(\sqrt n)
O(n) 的, 所以求
φ
(
N
)
\varphi(N)
φ(N) 也就是
O
(
n
)
O(\sqrt n)
O(n) 的
具体见代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n, m;
int main()
{
int T;
cin >> T;
while (T -- )
{
cin >> n;
int res = n;
for (int i = 2; i <= n / i; i ++ )
{
if (n % i == 0)
{
res = res / i * (i - 1); // 相当于res * (1 - 1 / i), 这样是为了防止出现小数, 下取整没了, 最主要的就是这里
while (n % i == 0) n /= i;
}
}
if (n != 1) res = res / n * (n - 1); // 这里不要忘记
cout << res << endl;
}
return 0;
}
一个数欧拉函数的大小和质因数的次幂无关
更快点?要不要试试先把质数筛出来?这样也可减少一定的时间。
筛法求欧拉函数
O
(
n
)
O(n)
O(n)
这里写的注释很好,就不多重打了。
是用线性筛顺便筛出欧拉函数,首先,线性筛可以筛出质数 p,质数的欧拉函数很好求,因为一个质数在
[
1
,
p
]
[1, p]
[1,p] 中除了 p 本身以外,其他所有数都与它互质,所以
φ
(
p
)
=
p
−
1
\varphi(p) = p - 1
φ(p)=p−1。
而对于筛掉的数,我们可以知道,筛掉的数是用这个数 u 的最小质因子 p 筛去的,唉?质因子是质数吧,按算法运行顺序来说, u 是由
p
×
i
p \times i
p×i 得到的,那么 i 是整数,且肯定比 u 小,按理说,它的欧拉函数我已经求出来了。而
φ
(
p
)
=
p
−
1
\varphi(p) = p - 1
φ(p)=p−1,我们还知道一个等式。
即
φ
(
a
b
)
=
φ
(
a
)
×
φ
(
b
)
×
gcd
(
a
,
b
)
φ
(
gcd
(
a
,
b
)
)
\varphi(ab) = \frac {φ(a) \times φ(b) \times \gcd(a,b)}{φ(\gcd(a,b))}
φ(ab)=φ(gcd(a,b))φ(a)×φ(b)×gcd(a,b)
那么就可以得出来了
φ
(
u
)
=
φ
(
i
×
p
)
=
φ
(
p
)
×
φ
(
i
)
×
gcd
(
p
,
i
)
φ
(
gcd
(
i
,
p
)
)
\varphi(u) = \varphi(i \times p) = \frac {\varphi(p) \times \varphi(i) \times \gcd(p,i)}{\varphi(\gcd(i,p))}
φ(u)=φ(i×p)=φ(gcd(i,p))φ(p)×φ(i)×gcd(p,i)
其中因为
p
p
p 是质数,而
p
<
=
i
p <= i
p<=i ,并且 p 是 i 的质因子,所以
gcd
(
i
,
p
)
=
p
\gcd(i,p) = p
gcd(i,p)=p,所以
φ
(
gcd
(
p
,
i
)
)
=
φ
(
p
)
\varphi(\gcd(p,i)) = \varphi(p)
φ(gcd(p,i))=φ(p)
所以有下式
φ
(
u
)
=
φ
(
i
×
p
)
=
p
×
φ
(
i
)
\varphi(u) = \varphi(i \times p) = {p \times \varphi(i)}
φ(u)=φ(i×p)=p×φ(i)
在注释里还有一种解释方法,这里就不说了。
/*
线性筛可以求出很多附加的东西
具体会在代码里写注释
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1000010;
int n;
int primes[N], cnt;
bool st[N];
int phi[N]; // phi[i] 是i的欧拉函数
LL sum;
int main()
{
cin >> n;
phi[1] = 1; // 1的欧拉函数是1, 需要手动写上
for (int i = 2; i <= n; i ++ )
{
if (st[i] == 0)
{
primes[ ++ cnt] = i;
sum += phi[i] = i - 1; // 首先如果i是质数, 质数和所有数都互质(除了它自己), 那么对于质数i的φ, 就是i - 1
}
for (int j = 1; primes[j] <= n / i; j ++ )
{
st[i * primes[j]] = true;
if (i % primes[j] == 0) // 如果i % pj == 0 那么pj就是i的最小质因数(这点在线性筛里提到过)
{ // 说明i的质因数包括pj, 那么φ(i)里面包括 (1 - 1/pj), 一个数欧拉函数的大小和其质因数的次幂无关, 根据φ(N) = N * (1 - 1/p1) * (1 - 1/p2) * ... * (1 - 1/pk);
sum += phi[i * primes[j]] = phi[i] * primes[j]; // pj * i 比 i 只多了一个pj而且pj还在i的质因数里面, 那么 φ(i*pj)只比φ(i)多一个pj 也就是 φ(i*pj) = φ(i) * pj
break;
}
sum += phi[i * primes[j]] = phi[i] * (primes[j] - 1); // 和上面同理, 但是pj不是i的质因数, 所以φ(i) 不包含 (1 - 1/pj), φ(pj*i)需要加上这个
}
}
cout << sum + 1 << endl;
return 0;
}