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}$$
有:

\[\LARGE φ(n)=n\times (1- \frac{1}{p_1})\times (1- \frac{1}{p_2}) \times ... \times (1- \frac{1}{p_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\)

欧拉函数公式,只与因子相关,与指数无关!
还是上面的栗子:

\[\LARGE 8=2^3 \\ φ(8)=8*(1-\frac{1}{2})=4\]

四、欧拉函数公式证明

欧拉函数的证明是使用的融斥原理,从定义出发:
定义:欧拉函数是小于\(n\)的数中与\(n\)互质的数的数目。

(1)对数字\(N\)进行质因数分解:

\[\LARGE N={p_1}^{r_1} \cdot {p_2}^{r_2} \cdot {p_3}^{r_3} \cdot ... \cdot {p_k}^{r_k} \]

(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\)个!为什么呢?

\[\LARGE \displaystyle \left \lfloor \frac{10}{2} \right \rfloor=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;
}
posted @ 2021-09-27 09:43  糖豆爸爸  阅读(331)  评论(0编辑  收藏  举报
Live2D