来源:http://acm.fzu.edu.cn/problem.php?pid=1012
概述:计算不大于n而和n互素的正整数的个数。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
参考文献:陈景润,《初等数论II》第五章,百度网盘下载,以下截图均来自参考文献。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
理论分析
其实,题目要计算的正是欧拉函数:
推导和详细内容,可以参阅《初等数论II》,这里只需记住该结论:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
编程求解
关键是写出欧拉函数。
1、函数命名上,常见的是euler,也可以使用希腊字母φ的拉丁语写法:phi。这里我用euler,而以后如果要保存返回值,变量名用phi。
2、找n的质因数:利用《数论》里的知识,n最小的约数一定是它的质因数。ans记录答案,先初始化为1。i从2开始遍历,每找到一个质因数,ans先自乘i-1,n自除i,然后进入while循环,判断该质因数的次幂大小。当i*i>n时,n不能再分解为两个及以上约数相乘,故跳出循环。然后要判断n是否不等于1,即最后的n本身也是一个的质因数时,ans需要自乘n-1。
#include <cstdio>
using namespace std;
int euler(int n)
{
int i, ans = 1;
for (i = 2; i*i <= n; i++)
{
if (n%i==0)
{
ans *= i-1, n /= i;
while (n%i==0) ans *= i, n /= i;
}
}
if (n!=1) ans *= n-1;
return ans;
}
int main()
{
int n;
do
{
scanf("%d", &n);
if (n) printf("%d\n", euler(n));
else break;
}while (1);
return 0;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
扩展应用:欧拉函数在以后的快速幂模运算中将会有大用场,记得保存好该模板。