AcWing 873. 欧拉函数
\(AcWing\) \(873\). 欧拉函数
一、题目描述
给定 \(n\) 个正整数 \(a_i\),请你求出每个数的欧拉函数。
欧拉函数的定义
输入格式
第一行包含整数 \(n\)。
接下来 \(n\) 行,每行包含一个正整数 \(a_i\)。
输出格式
输出共 \(n\) 行,每行输出一个正整数 \(a_i\) 的欧拉函数。
数据范围
\(1≤n≤100,1≤a_i≤2×10^9\)
输入样例:
3
3
6
8
输出样例:
2
2
4
二、欧拉函数定义
定义:欧拉函数是小于\(n\)的数中与\(n\)互质的数的数目。
例如\(\LARGE φ(8)=4\),因为\(\LARGE 1,3,5,7\)均和\(\LARGE 8\)互质。
三、欧拉函数公式
如果\(n\)的唯一分解式:$$\LARGE n=p_1^{r_1}\cdot p_2^{r_2} \cdot...\cdot p_k^{r_k}$$
有:
对比与复习,复习办法(用纸笔抄公式记忆+打代码记忆):
-
约数个数:只与 幂次 相关,与质因子无关
\(180= 2^2 * 3^2 * 5\)
约数个数\(=(1+2) * (1+2) * (1+1) =18\) -
约数和:与质数因子和幂次都相关
以\(360\)举例,求它的全部约数和:
\(360 = 2*2*2*3*3*5 =2^3 * 3^2 * 5^1\)
约数和=\((2^0+2^1+2^2+2^3)*(3^0+3^1+3^2)*(5^0+5^1) = (1+2+4+8)*(1+3+9)*(1+5)= \\ 15*13*6=1170\)
欧拉函数公式,只与因子相关,与指数无关!
还是上面的栗子:
四、欧拉函数公式证明
欧拉函数的证明是使用的融斥原理,从定义出发:
定义:欧拉函数是小于\(n\)的数中与\(n\)互质的数的数目。
(1)对数字\(N\)进行质因数分解:
(2) 如果一个数包含了\(\LARGE p_1\)这个因子,那么它肯定与\(N\)不互质,因为有\(\LARGE p_1\)这个公因子嘛,换句话说,就是要想与\(N\)互质,那么一定不能包含\(\LARGE p_1,p_2,...,p_k\)这此因子。
小于\(N\)的所有数字中,如果它包含了\(\LARGE p_1,p_2,...,p_k\)这样的因子的话,那么它就与\(N\)不互质,换句话说,只要把小于\(N\)之内,所有包含\(\LARGE p_1,p_2,..p_k\)的数字都干掉,剩下的就是与\(N\)互质的数。所谓包含\(\LARGE p_1,p_2,..,p_k\)其实也就是
\(\LARGE p_1,p_2,..,p_k\)的整数倍。
- 把\(\LARGE p_1\)的倍数从\(\LARGE N\)中减去,那需要减去多少个呢?
\(\LARGE \displaystyle \left \lfloor \frac{N}{p_1} \right \rfloor\)个.
这里想不明白的话,可以举个栗子:比如\(N=10\),\(p_1=2\),有几个\(p_1\)的倍数呢?\(5\)个!为什么呢?
(3) 把\(\LARGE p_2,p_3,...,p_k\)的倍数都减去吧,分别减去\(\LARGE \left \lfloor \frac{N}{p_2}\right \rfloor\),\(\LARGE \left \lfloor \frac{N}{p_3}\right \rfloor\),...,\(\LARGE \left \lfloor \frac{N}{p_k}\right \rfloor\)个。
(4) 这么干是减多了的,比如某个数,是\(\LARGE p_2\)的倍数,也是\(\LARGE p_3\)的倍数,就减了两回,还需要再加回来\(\LARGE p_i * p_j\)的倍数,就是 + \(\LARGE \frac{N}{p_1 * p_2}\)+ \(\LARGE \frac{N}{p_1 * p_3}\)+ \(\LARGE \frac{N}{p_1 * p_k}\)+ ....
(5)将公式\(\LARGE \phi(N)=N * (1-\frac{1}{p_1}) * (1-\frac{1}{p_2}) * (1-\frac{1}{p_3}) * ... * (1-\frac{1}{p_k})\)展开,发现就是上面的东东了,证毕。
(6)
$\LARGE \phi(N)=N * (1-\frac{1}{p_1}) * (1-\frac{1}{p_2}) * (1-\frac{1}{p_3}) * ... * (1-\frac{1}{p_k}) \
\Leftrightarrow \
\phi(N)=N * (\frac{p_1-1}{p_1}) * (\frac{p_2-1}{p_2}) * (\frac{p_3-1}{p_3}) * ... * (\frac{p_k-1}{p_k})
$
下面在编码计算单个数字的欧拉函数值时,要用到这个变形。
五、求单个数字的欧拉函数
#include <bits/stdc++.h>
using namespace std;
int phi(int x) {
int res = x;
for (int i = 2; i <= x / i; 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;
}
int main() {
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
printf("%d\n", phi(x));
}
return 0;
}