函数Eural就是欧拉公式的模板了,这里还是要有些注意的在在乘以(i-1)/i的时候,我们是先除再乘的,为什么这样做呢?因为这样可以避免中间结果的溢出,?
而在for循环里边的条件写的也很有意思,我们并没有直接循环到N而是循环到了N??√,如果是22的话,那么岂不是循环到4就结束了么?别担心,N是动态变化的,而且我们可以保证N循环结束的时候是质数或者为1,因为不存在两个大于N??√的因子,如果有的话,那么他们乘积一定大于N,所以最多存在一个大于N??√的因子,而最后的一个if(),就补上了这个漏洞.?
那么读完了代码,你是否还是觉得哪里不对劲?没错,我们没有确认i是否为质数,为什么还是正确的呢?假设存在一个i为非质数,且N%i==0,因为N%i==0,且i非质数,那么gcd(N,i)=a ,a!=1,那么在i==a的时候我们就可以发现这种情况是不存在的,因为N%a一定等于0,而在if语句中我们用while循环出去了N中所有的a,故之后N%i一定不会为0的.故i一定为质数.?
arkdown写东西,感觉很新奇.
题意的要求是给出一个数N求小于N与N不互质的数,而N相当打,显然用暴力一个一个的求显然是行不通的,那么我们应该怎么办呢??
既然求与他不互质的很烦,我们我们尝试去求与他互质的数目,再拿N减去不就好了么??
#include<stdio.h>
using namespace std;
__int64 eural(__int64 n)
{
__int64 res = n;
for(int i = 2;i*i <= n;i++)
{
if(n % i == 0)
res = res/i*(i-1);
while(n % i == 0)
n /= i;
}
if(n > 1)
res = res/n*(n - 1);
return res;
}
int main()
{
__int64 n;
while(scanf("%I64d",&n),n)
printf("%I64d\n",n - 1 - eural(n));
return 0;
}
HDU1787 GCD again 欧拉公式 的运用
最新推荐文章于 2020-05-27 19:13:24 发布