1 条题解
-
0
题目理解
题目要求我们计算一个正整数
n的欧拉函数值φ(n),即小于n且与n互质的正整数的个数。两个数互质是指它们的最大公约数为1。例如:n = 7时,小于7且与7互质的数为1, 2, 3, 4, 5, 6,共6个,所以φ(7) = 6。n = 12时,小于12且与12互质的数为1, 5, 7, 11,共4个,所以φ(12) = 4。
解题思路
欧拉函数的计算基于
n的质因数分解。具体步骤如下:- 质因数分解:将
n分解为质因数的乘积。例如,12 = 2^2 * 3^1。 - 应用欧拉函数公式:
- 如果
n是一个质数p,则φ(p) = p - 1。 - 如果
n可以分解为质因数的乘积n = p1^k1 * p2^k2 * ... * pm^km,则欧拉函数值为: $ φ(n) = n \times \left(1 - \frac{1}{p1}\right) \times \left(1 - \frac{1}{p2}\right) \times \dots \times \left(1 - \frac{1}{pm}\right) $ - 例如,
12 = 2^2 * 3^1,所以: $ φ(12) = 12 \times \left(1 - \frac{1}{2}\right) \times \left(1 - \frac{1}{3}\right) = 12 \times \frac{1}{2} \times \frac{2}{3} = 4 $
- 如果
标程
#include <functional> #include <algorithm> #include <iostream> #include <fstream> #include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <queue> #include <stack> #include <map> #include <bitset> #include <set> #include <vector> using namespace std; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; const double eps = 1e-15; typedef long long LL; typedef pair <int, int> PLL; int getphi(int n) { int ans = n; for (int i = 2; i * i <= n; ++i) { if (n % i == 0) { ans -= ans / i; while (n % i == 0) { n /= i; } } } if (n > 1) { ans -= ans / n; } return ans; } int main() { int n; while (~scanf("%d", &n), n) { printf("%d\n", getphi(n)); } return 0; }代码解析
-
函数
getphi:- 初始化
ans为n。 - 遍历从2到
sqrt(n)的所有整数i,检查是否能整除n:- 如果能整除,说明
i是n的一个质因数,更新ans为ans - ans / i,并将n中所有i的因子除尽。
- 如果能整除,说明
- 如果剩余的
n大于1,说明n本身是一个质数,更新ans为ans - ans / n。 - 返回
ans作为欧拉函数值。
- 初始化
-
主函数
main:- 使用
scanf读取输入的n,直到n为0为止。 - 对于每个
n,调用getphi函数计算φ(n)并输出结果。
- 使用
复杂度分析
- 时间复杂度:质因数分解的时间复杂度为
O(sqrt(n)),因为最多需要遍历到sqrt(n)。 - 空间复杂度:
O(1),只使用了常数级别的额外空间。
总结
通过质因数分解和应用欧拉函数的公式,我们可以高效地计算出
φ(n)。这种方法避免了逐个检查每个数是否与n互质,显著提高了计算效率,尤其适用于大数(n高达1,000,000,000)的情况。
- 1
信息
- ID
- 1408
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者