FOJ 1012 Relatives

       来源:http://acm.fzu.edu.cn/problem.php?pid=1012

       概述:计算不大于n而和n互素的正整数的个数。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参考文献:陈景润,《初等数论II》第五章,百度网盘下载,以下截图均来自参考文献。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

理论分析

       其实,题目要计算的正是欧拉函数:

       推导和详细内容,可以参阅《初等数论II》,这里只需记住该结论:

FOJ 1012 Relatives_第1张图片

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

编程求解

       关键是写出欧拉函数。

       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;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

 扩展应用:欧拉函数在以后的快速幂模运算中将会有大用场,记得保存好该模板。

你可能感兴趣的:(欧拉函数)