本题目实际就是求一个数的欧拉函数。
这题目我用了素数表,欧拉函数。
解释一下欧拉函数,欧拉函数就是求一个数,例如n,那么小于n的所有和n互质的数的个数。
欧拉函数是,我们都知道,n可以分解成质数的不同幂次 的乘积,n=p1^a1*p2^a2*p3^a3……
那么欧拉函数就是n*(1-1/p1)*(1-1/p2)*(1-1/p3)……
#include<iostream>
using namespace std;
const int M = 3000500;
int p[400010], pNum;
bool f[M];
void Prime()
{
int i, j;
for(i = 2; i < M; i++) {
if(!f[i]) { p[pNum++] = i; }
for(j = 0; j < pNum && p[j] * i < M; j++ ) {
f[p[j]*i] = 1;
if(!(i%p[j]))
break;
}
}
}
int main()
{
int N,i,cnt,tmp,flag;
double sum;
Prime();
while(scanf("%d",&N),N)
{
tmp=N;
i=0;
cnt=0;
sum=1;
while(i<=pNum)
{
if(N==1)
break;
flag=0;
while(N%p[i]==0)
{
flag=1;
N/=p[i];
}
if(flag==1)
sum*=(1.0-1.0/p[i]);
i++;
}
printf("%d/n",(int)(sum*tmp));
}
return 0;
}
下面是一个很强大的代码。
/*//无敌代码
while(scanf("%d",&n),n != 0){
if(n == 1){
printf("0/n"); continue;
}
ans = n;
for(int i = 2;i*i <= n;++i){
if( n % i == 0 ){
ans = ans - ans/i;除去所有ans一下的和ans有公约数的数。
while(n%i == 0){//不用筛选素数,如:如果i=4,其实已经被2除完了,6,已被2,3约完了
n /= i;
}
}
}
// n is prime itself
if(n != 1) ans = ans - ans / n;//如果n是质数,那么欧啦函数=n-1
printf("%d/n",ans);
}
*/