poj2047

来源:互联网 发布:java内存管理机制 编辑:程序博客网 时间:2024/06/06 12:46

本题目实际就是求一个数的欧拉函数。

这题目我用了素数表,欧拉函数。

解释一下欧拉函数,欧拉函数就是求一个数,例如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);
    }
*/