典型的欧拉函数应用,关于欧拉函数介绍如下:
欧拉函数φ(n)是用来求少于或等于n的数中与n互质的数的数目
公式如下:
φ(n)=n*(1-1/p[1])*(1-1/p[2])*...*(1-1/p[k])//p[i]用来指n的第i个素因子
有公式就很好求解了,现在的问题就是怎么找到小于等于n且与n互质的因子呢
很容易处理,我们从2开始遍历到sqrt(n+0.5)
期间遇到n的因子x,令n把因子x除尽(n/x知道x与n互质)即可保证之后遇到的因子均为n的质因子
这样做的原因是什么呢?
很简单,因为n的某个非质因子必然由更小的质因子相乘得到,因此在遇到这个非质因子之前,除尽更小的质因子,即可保证该非质因子不会出现
代码实现如下:
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 10010
#define LL long long
using namespace std;
LL euler_phi(LL n) {
LL m = (LL)sqrt(n+0.5);
LL ans = n;
for(int i=2; i<=m; ++i) {
if(n % i == 0) {
ans = ans/i*(i-1);这里先乘后除会快很多
while(n%i == 0)
n /= i;
}
}
if(n > 1)//这里处理的原因见代码下面解释
ans = ans/n*(n-1);
return ans;
}
int main(void) {
LL n;
while(cin >> n, n) {
cout << euler_phi(n) << endl;
}
return 0;
}
为什么还要对n单独处理呢?
原因很简单:
对应的是n本身就是一个质数的情况,这时答案恰好为(n-1)
一个很神奇的现象就是我把乘除的顺序换了下,时间就快了很多
具体原因我也不太清楚,应该和计算机的底层实现有关吧,哪位朋友了解的话还希望不吝赐教