從「最簡真分數的個數」談起

      所謂最簡真分數是一個分數的分子小於分母,且分子分母無公因數。
      2010年湖北省小學奧林匹克數學競賽(小學六年級組)有這樣一道試題:以2010爲分母的最簡真分數有多少個?
      這道小學奧數試題考察的是學生對集合包含和容斥知識的掌握狀況。
      因爲2010=2*3*5*67(分解質因數),所以以2010爲分母的最簡真分數的分子必須小於2010且不能被二、三、5或67整除。
      小朋友解決這個問題的計算過程以下:
      在1~2010共2010個數中,
      能被2整除的數有 2010÷2=1005
      能被3整除的數有 2010÷3=670
      能被5整除的數有 2010÷5=402
      能被67整除的數有 2010÷67=30
      能同時被2和3整除的數有 2010÷(2×3)=335
      能同時被2和5整除的數有 2010÷(2×5)=201
      能同時被2和67整除的數有 2010÷(2×67)=15
      能同時被3和5整除的數有 2010÷(3×5)=134
      能同時被3和67整除的數有 2010÷(3×67)=10
      能同時被5和67整除的數有 2010÷(5×67)=6
      能同時被二、3和5整除的數有 2010÷(2×3×5)=67
      能同時被二、3和67整除的數有 2010÷(2×3×67)=5
      能同時被二、5和67整除的數有 2010÷(2×5×67)=3
      能同時被三、5和67整除的數有 2010÷(3×5×67)=2
      能同時被二、三、5和67整除的數有 2010÷(2×3×5×67)=1
      這樣,1~2010中能被2或3或5或67整除的數有
        (1005+670+402+30)-(335+201+15+134+10+6)+(67+5+3+2)-1
       =2107-701+77-1   =1482
      所以,1~2010中既不能被2整除,也不能被3整除,也不能被5整除,也不能被67整除的數有 2010-1482=528 個。
      即以2010爲分母的最簡真分數有528個。php

      咱們能夠看出,上面的計算過程是比較繁瑣的,須要認真仔細。
      學習過程序設計後,能夠編寫了一個簡單的循環程序解決這個問題。
      用一個變量cnt來保存最簡真分數的個數,初始值爲0。
      對1~2010中的每個數num,進行判斷,這是一個循環,寫成
             for(num=1; num<=2010;num++)
      循環體中的判斷方法爲:若是num既不能被2整除,也不能被3整除,也不能被5整除,也不能被67整除,則計數。寫成
       if(num%2!=0 && num%3!=0 && num%5!=0 && num %67!=0)
              cnt++;
      最後,輸出結果cnt。   一個簡單的程序,就獲得問題的答案。
   編寫的源程序以下:
       #include <stdio.h>
       int main()
       {
             int cnt,num;
             cnt=0;
             for (num=1; num<=2010;num++)
                  if (num%2!=0 && num%3!=0 && num%5!=0 && num %67!=0)
                       cnt++;
             printf("%d\n",cnt);
             return 0;
       }html

      須要說明的是,當時競賽的真題是:全部以2010爲分母的最簡真分數的和爲多少?編程

      瞧瞧,做爲大學生的你還能像小朋友同樣作出來嗎?數組

      固然,你學過程序設計,將上面的程序簡單改寫一下,能夠很快獲得答案的。何必像小朋友同樣苦苦思考和運算呢。函數

#include <stdio.h>
int main()
{
     int num;
     double sum;
     sum=0;
     for (num=1; num<=2010;num++)
         if (num%2!=0 && num%3!=0 && num%5!=0 && num %67!=0)
               sum+=1.0*num/2010;
     printf("%lf\n",sum);
     return 0;
}學習

      程序運行後,輸出 264.000000。即全部以2010爲分母的最簡真分數的和是264。網站

      小朋友是無法像程序同樣硬算的。1/2010+7/2010+11/2010+…+2099/2010=264。spa

      小朋友有小朋友的聰明,1/2010是最簡真分數,那麼2099/2010 也必定是最簡真分數。設計

      i/2010 是最簡真分數,那麼 (2010-i)/2010 也必定是最簡真分數。htm

      1/2010 + 2099/2010=1         i/2010 +(2010-i)/2010=1。

      小朋友知道了以2010爲分母的最簡真分數有528個,所以它們的和爲 528/2 = 264。

      由於2010分解質因數後,因數有二、三、5和67四個,用於考察集合的包含與容斥計算量略大但又能夠完成,能夠算是一道很好的競賽試題。

     在這道試題的基礎上,咱們看這樣一個問題。

【例1】最簡真分數。

      任意輸入一個正整數n,求以n爲分母的最簡真分數有多少個?

     (1)編程思路1。

      將輸入的n做爲分母,窮舉分子i (1≤i≤n-1)。所以,程序可先寫成以下的循環:

         for (i=1; i<=n-1; i++)
        {
               對每一分數i/n,進行是否存在公因數的檢測。根據檢測的結果決定是否計數;
        }
      在上面的循環體中須要對每一分數i/n,進行是否存在公因數的檢測。若是分子i與分母n存在大於1的公因數k,說明i/n不是最簡真分數,不予計數。怎樣進行檢測呢?
      由於公因數k的取值範圍爲[2,i],於是設置u循環在[2,i]中窮舉k,若知足條件
            i%k==0 && n%k==0
      說明分子分母存在公因數k,標記t=1後退出。
      在對因子k進行循環窮舉前,可設置標誌t=0。退出因子窮舉循環後,若t=1,說明分子和分母存在公因子;若保持原t=0,說明分子分母無公因數,統計個數。

      (2)源程序1。

#include <stdio.h>
int main()
{
      int n,i,k,t,cnt;
      while (scanf("%d",&n) && n!=0)
      {
           cnt=0;
           for (i=1;i<=n-1;i++)       // 窮舉分子
           {
                t=0;
                for (k=2;k<=i;k++)  // 窮舉因數
                    if (i%k==0 && n%k==0)
                    {
                         t=1;
                         break;          // 分子分母有公因數捨去
                    }
               if (t==0)
                     cnt++;           // 統計最簡真分數個數
          }
          printf("%d\n",cnt);
      }
      return 0;
}

      將上面的源程序提交給 POJ 2407 「Relatives」,斷定爲Time Limit Exceeded。  POJ 2407的題意是: 輸入正整數N,求小於或等於N ([1,N]),且與N互質的正整數(包括1)的個數。這與求最簡真分數的意思徹底一致。

      上面源程序1的方法簡單直接,但對於N值較大的話,會超時的。所以,咱們應找到快速的求法。在數論中,歐拉函數就很好地解決了這樣的問題。

      在數論,對於正整數n,歐拉函數是小於或等於n的正整數中與n互質的數的數目。此函數以其首名研究者歐拉命名,通常簡記爲φ函數。 例如,φ(8)=4,由於1,3,5,7均和8互質。

      通常來講,設正整數N分解質因數後,N=P1^q1*P2^q2*...*Pn^qn.

      則   φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn)。

      例如, 10= 2*5     φ(10)=10×(1-1/2)×(1-1/5)=4;     這4個數是1, 3, 7, 9 。

         30=2*3*5   φ(30)=30×(1-1/2)×(1-1/3)×(1-1/5)=8;  這8個數是1,7,11,13, 17, 19, 23, 29。

       按歐拉函數的求法,能夠編寫以下的源程序。

      (3)源程序2。

#include <stdio.h>
int main()
{
      int n,i,ans,t;
      while (scanf("%d", &n) && n!=0)
      {
            ans = n;
            t=n;
            for (i=2;i*i<=t;i++)
                if (t % i == 0)                 // 找到一個質因數i
                 {
                      ans -= ans/i;
                      while (t % i == 0)    // 將質因數i全去掉
                               t /= i;
                 }
            if (t!=1) ans -= ans/t;
            printf("%d\n",ans);
      }
      return 0;
}

      將源程序2提交給 POJ 2407, 能夠Accepted。

      將此源程序的printf("%d\n",ans);改寫爲 printf("%d\n",n-ans-1); 後,提交給 HDU 1787 「GCD Again」,也能夠Accepted。

【例2】仍是最簡真分數。

      輸入一個正整數n,求分母在指定區間[2,n]的最簡真分數共有多少個?

      例如,輸入5,輸出應爲 9。這9個最簡真分數是 {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5} 。

      (1)編程思路。

      例1的源程序2能夠求歐拉函數φ(n)的值。用一個循環求出 φ(2)+φ(3)+…+φ(n)的累加和,即得本題的輸出。

      (2)源程序。

#include <stdio.h>
int main()
{
      int n,i,k,ans,t,sum;
      while (scanf("%d", &n) && n!=0)
      {
           sum=0;
           for (k=2;k<=n;k++)
           {
                 ans = k;
                 t=k;
                 for (i=2;i*i<=t;i++)
                     if (t % i == 0)              // 找到一個質因數i
                     {
                          ans -= ans/i;
                          while (t % i == 0)   // 將質因數i全去掉
                               t /= i;
                      }
                 if (t!=1) ans -= ans/t;
                 sum+=ans;
          }
          printf("%d\n",sum);
      }
      return 0;
}

      將此源程序提交給 POJ 2478 「Farey Sequence」,被斷定爲Time Limit Exceeded。POJ 2478的題意是:求1~n的歐拉函數的和。

      由於,例1中是在 O(sqrt(n)) 的時間內求出一個數n的歐拉函數值。

      若是要求100000之內全部正整數的歐拉函數值,上面程序採用的方法的複雜度將高達O(N*sqrt(N))。所以,容易超時。

      下面咱們尋求更快的求歐拉函數值的方法。

      咱們知道,歐拉函數值  φ(n)=n*(1-1/p1)*(1-1/p2)....*(1-1/pk),其中p一、p2…pk爲n的全部質因子。即歐拉函數的值與其質因子有關。用篩法能夠方便地求出n之內的全部質數。關於篩法及應用能夠參閱本博客中的隨筆 POJ中和質數相關的三個例題(POJ 226二、POJ 273九、POJ 3006)

      那麼咱們能不能在篩法求質數的同時求出全部數的歐拉函數呢?能夠採用以下的方法:

      用篩法一邊篩出N之內的全部質數,一邊以相似於篩法的思想用質數篩出每一個數的歐拉函數φ值。

      這裏,利用了歐拉函數的幾個基本性質:

      ① 若N是質數p的k次冪,φ(N)=p^k-p^(k-1)=(p-1)p^(k-1),由於除了p的倍數外,其餘數都跟N互質。 
      ② 當N是質數時,φ(N) = N-1。顯然,由於N是質數,1~N-1均與N互質。 
      ③ 歐拉函數是積性函數——若m,n互質,φ(m*n)=φ(m)*φ(n) 。

      ④ 假設質數p能整除n,那麼

          若是p還能整除n / p ,  φ(n)  = φ(n / p) * p;
          若是p不能整除n / p,   φ(n)  = φ(n / p) * (p - 1)。

      定義數組phi[N],元素phi[i]表示正整數i的歐拉函數值φ(i)。

      定義數組vis[N],元素vis[i]=True表示i在篩子中,vis[i]=false表示i不在篩子中,已被篩掉。初始時,vis數組的元素全置爲true,表示所有放在篩子中。

     定義數組prime[N],元素prime[i]的值爲第i個質數。

      下面以求20之內全部質數及全部數的φ值爲例,來描述篩法的使用。

      1) 從i=2開始循環, vis[2]==true,找到第一個質數2,prime[0]=2,質數個數PNum=1;同時,phi[2]=2-1=1。

      採用循環 for (j = 0; j < pNum && prime[j]*i <MAXN; j++ ) 將篩子中2的各質數倍數篩掉,同時求得相應數的歐拉函數值。(注意這裏與一般的篩法有改變,主要爲了用質數篩出各數的歐拉函數值)。

      篩去 2*prime[0]=2*2=4,即 vis[4]=false; phi[4]=phi[2]*prime[0]=1*2=2;

      2)i++,進行下次循環, vis[3]==true,找到第2個質數,prime[1]=3,pNum=2,同時phi[3]=3-1=2。

     篩去 3*prime[0]=3*2=6 ,即vis[6]=false;  置phi[6]=phi[3]*(prime[0]-1)=2*1=2;

     篩去 3*prime[1]=3*3=9 ,即vis[9]=false;  置phi[9]=phi[3]*(prime[1])=2*3=6;

     3)i++,進行下次循環, vis[4]==false,4不是質數。

     篩去 4*prime[0]=4*2=8 ,即vis[8]=false;  置phi[8]=phi[4]*(prime[0])=2*2=4;

     篩去 4*prime[1]=4*3=12 ,即vis[12]=false;  置phi[12]=phi[4]*(prime[1]-1)=2*2=4; 

          與  φ(12)=12*(1-1/2)(1-1/3)=4   比較下 更容易理解。

         phi[12]=phi[4]*(prime[1]-1)=phi[2]*prime[0]*(prime[1]-1)=2*(1-1/2)*2*3*(1-1/3)。
      4)i++,進行下次循環, vis[5]==true,找到第3個質數,prime[2]=5,pNum=3,同時phi[5]=5-1=4。

     篩去 5*prime[0]=5*2=10 ,即vis[10]=false;  置phi[10]=phi[5]*(prime[0]-1)=4*1=4;

     篩去 5*prime[1]=5*3=15 ,即vis[15]=false;  置phi[15]=phi[5]*(prime[1]-1)=4*2=8;

     篩去 5*prime[2]=5*5=25 ,即vis[25]=false;   固然咱們以20爲例的話,25已超出,循環不會執行到。

      同理,6不是質數,篩去 6*2=12,置 phi[12]=phi[6]*(prime[0])= 2*2=4。

                                     篩去 6*3=18 ,置phi[18]=phi[6]*(prime[1])=2*3=6。

                 7是質數,置prime[3]=7,pNum=4, phi[7]=6。    

                                    篩去 7*2=14,置 phi[14]=phi[7]*(prime[0]-1)= 6*1=6。

          …… 

      (3)採用篩法思想的源程序。

#include <stdio.h>
#include <string.h>
#define MAXN 1000005
int prime[MAXN], pNum, phi[MAXN];
__int64 num[MAXN]={0};
bool vis[MAXN];
int main()
{
      int n,i,j;
      memset(vis,true,sizeof(vis));
      // 下面程序段既求MAXN之內的素數又求歐拉數。
      pNum=0;
      phi[1] = 1;
      for (i = 2; i < MAXN; i++)
      {
             if (vis[i])   //  i是素數
             {  
                   prime[pNum++] = i;
                   phi[i] = i-1;
             }
             for (j = 0; j < pNum && prime[j]*i <MAXN; j++ )
             {
                     vis[prime[j]*i] = false;
                     if (i % prime[j] == 0)
                     {
                           phi[i*prime[j]] = phi[i] * prime[j];
                           break;
                     }
                     else
                           phi[i*prime[j]] = phi[i] *(prime[j] - 1);
             }
       }
      for (i=2;i<MAXN;i++)
      {
            num[i]=num[i-1]+phi[i];
      }
      while (scanf("%d", &n) && n!=0)
      {
            printf("%I64d\n",num[n]);
      }
      return 0;
}

      將用篩法思想改寫的源程序提交給 POJ 2478, 能夠Accepted。

      將上面的程序略做改動,能夠順便經過 HDU 2824 「The Euler function」

    (4)進一步討論。

     上面採用篩法求歐拉函數的值時,用了3個數組,用於表示數是否在篩子中的標記數組vis,用於保存質數的數組prime,用於保存歐拉函數值的數組phi。雖然看起來直觀,好像體現了歐拉函數值與分解質因數相關的概念,但有點繁瑣。可否只用一個數組phi,即保存歐拉函數的值,又表示篩子,固然在篩子中的最小數必定是質數,從而又表示了質數呢?

       定義數組phi[N],初始值全爲0,Phi[i]=0表示i在篩子中,i是質數。

      前面介紹過歐拉函數值得標準求法。 

      設正整數N分解質因數後,N=P1^q1*P2^q2*...*Pn^qn.

       則   φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn)。

       顯然,若p1是n的質因數,phi[n]必定會做 n*(p1-1)/p1這樣的運算。

       下面我以n=30爲例介紹phi數組既保存歐拉函數值有當篩子用的方法。

       因爲篩法從i=2開始進行,全部phi[i]元素值初始全爲0。

      1)phi[2]=0,2在篩子中,2是質數,開始執行篩法過程,對指定範圍內全部2的倍數進行處理。

          phi[2]=0   phi[2]=2   (置初始值表示篩掉 )   phi[2]=phi[2]*(2-1)/2 =1   (因爲2是其質因數,按公式需 *(1-1/2)  )

          phi[4]=0   phi[4]=4   (置初始值表示篩掉 )   phi[4]=phi[4]*(2-1)/2 = 2  ( 因爲2是其質因數,按公式需 *(1-1/2)  )

          phi[6]=0   phi[6]=6                                           phi[6]=phi[6]*(2-1)/2 = 3

            ……

          phi[30]=0   phi[30]=30                                     phi[30]=phi[30]*(2-1)/2 = 15

      2)i++進行下一次循環。i=3,phi[3]=0,3在篩子中,3是質數,開始執行篩法過程,對指定範圍內全部3的倍數進行處理。     

           phi[3]=0   phi[3]=3   (置初始值表示篩掉 )   phi[3]=phi[3]*(3-1)/3 =2   (3是其質因數,按公式需 *(1-1/3) )

           phi[6]=3  不等於0,已篩過,再也不置初始值,直接phi[6]=phi[6]*(3-1)/3 =2  (3是其質因數,按公式需 *(1-1/3) ) 

           phi[9]=0   phi[9]=9   (置初始值表示篩掉 )   phi[9]=phi[9]*(3-1)/3 =6   (3是其質因數,按公式需 *(1-1/3) )

           ……

          phi[30]=15                                                       phi[30]=phi[30]*(3-1)/3 = 10

      3)i++進行下一次循環,i=4,phi[4]=2,4不在篩子中,4不是質數,不進行處理。

      4)i++進行下一次循環。i=5,phi[5]=0,5在篩子中,5是質數,開始執行篩法過程,對指定範圍內全部5的倍數進行處理。     

           phi[5]=0   phi[5]=5   (置初始值表示篩掉 )   phi[5]=phi[5]*(5-1)/5 =4   (5是其質因數,按公式需 *(1-1/5) )

           phi[10]=5  不等於0,已篩過,直接              phi[10]=phi[10]*(5-1)/5 =4  (5是其質因數,按公式需 *(1-1/5) ) 

            ……

          phi[30]=10                                                      phi[30]=phi[30]*(5-1)/5 = 8

       根據上面的描述,能夠將這個篩法過程寫成以下的二重循環。

for (i=2; i <= n; i++)
{
        if (phi[i]==0)                   // i在篩子中,是質數
        for (j = i; j <= n; j+=i)     // 處理i的倍數
        {
              if (phi[j]==0) // 在篩子中,篩掉
                      phi[j] = j;
              phi[j] = phi[j]/i*(i-1);
         }
}

      請本身採用這種只用一個數組的篩法過程改寫上面的篩法程序。

 【例3】歐拉函數的應用。

       輸入一個正整數N(1 ≤ N ≤ 1000000000),求1~N-1中全部與N不互質的數的和。兩個正整數a和b,若是a和b的最大公約數gcd(a,b)>1,則a與b不互質。因爲所求和值較大,輸出其模1000000007的結果。

      (1)編程思路。

       先需明白一個簡單的定理:若 gcd(n,i)=1,則 gcd(n,n-i)=1。 即若是n與i互質,則n與n-i必定互質。

      所以,本題咱們能夠先求全部與n互質的數的和sum。因爲與n互質的數兩兩配對(i與n-i)的和爲n。這樣,

            sum=n* phi(n)/2 。   phi(n)是歐拉函數,其值爲1~n中全部與n互質的數的個數。因爲題目中N值較大,篩法用數組保存不恰當,所以直接採用例1中得源程序2的思路求歐拉函數的值。

       求得sum後,輸出的答案應爲 [(n-1)*n/2-sum] % 1000000007 。 

      (2)源程序。

#include <stdio.h>
#define MOD 1000000007
int main()
{
      __int64 n,t,sum,ans;
      int i;
      while (scanf("%I64d", &n) && n!=0)
      {
              sum = n;
              t=n;
              for (i=2;i*i<=t;i++)
                   if (t % i == 0) // 找到一個質因數i
                   {
                          sum -= sum/i;
                          while (t % i == 0) // 將質因數i全去掉
                                 t /= i;
                    }
            if (t!=1) sum -= sum/t;
            ans=n*(n-1)/2;
            sum=n*sum/2;
            ans=(ans-sum)% MOD;
            printf("%d\n",ans);
      }
      return 0;
}

將此源程序提交給 HDU 3501 「Calculation 2」,能夠Accepted。

       

      上面咱們介紹了三種求歐拉函數值的方法。一種是直接利用公式計算,另兩種是利用篩法,這兩種篩法實際上有兩個名稱的,一個稱爲歐拉篩求歐拉函數(採用3個數組的那個),一個稱爲 埃拉託斯特尼篩求歐拉函數(採用一個數組的那個)。因爲歐拉函數在ACM、NOIP等競賽中是一個基礎知識,在POJ、HDU等在線OJ網站中也有較多相關的題目。所以,咱們能夠將這3種方法寫成函數的形式,之後做爲模板直接套用或直接應用便可。

      下面咱們用POJ 1284爲例,來展現抽象的3個函數及應用狀況。

【例4】Primitive Roots。(POJ 1284)

We say that integer x, 0 < x < p, is a primitive root modulo odd prime p if and only if the set { (xi mod p) | 1 <= i <= p-1 } is equal to { 1, ..., p-1 }. For example, the consecutive powers of 3 modulo 7 are 3, 2, 6, 4, 5, 1, and thus 3 is a primitive root modulo 7.
Write a program which given any odd prime 3 <= p < 65536 outputs the number of primitive roots modulo p.
Input

Each line of the input contains an odd prime numbers p. Input is terminated by the end-of-file seperator.
Output

For each p, print a single number that gives the number of primitive roots in a single line.
Sample Input

23
31
79
Sample Output

10
8
24

      本題的意思是:若p是質數,則p有 phi(p-1)個原根。輸入n,求歐拉函數phi(n-1)的值。

      (1)採用公式直接計算歐拉函數。 

#include <stdio.h>
int getPhiValue(int n)         // 求n的歐拉函數值phi(n)
{
      int i,sum,t;
      sum = n;
      t=n;
      for (i=2;i*i<=t;i++)
           if (t % i == 0) // 找到一個質因數i
           {
                sum -= sum/i;
                while (t % i == 0)       // 將質因數i全去掉
                        t /= i;
           }
      if (t!=1) sum -= sum/t;
      return sum;
}
int main()
{
      int p;
      while (scanf("%d", &p) !=EOF)
      {
            printf("%d\n",getPhiValue(p-1));
      }
      return 0;
}

      (2)採用埃拉託斯特尼篩求歐拉函數。

#include <stdio.h>
#include <string.h>
#define MAXN 65536
int phi[MAXN];
void getPhiTable(int n) // 求2~n的歐拉函數值phi[i] (1<i<=n)
{
      int i,j;
      memset(phi,0,sizeof(phi));
      phi[1]=1;
      for (i=2; i <= n; i++)
      {
            if (phi[i]==0)                    // i在篩子中,是質數
            for (j = i; j <= n; j+=i)       // 處理i的倍數
            {
                  if (phi[j]==0)              // 在篩子中,篩掉
                          phi[j] = j;
                  phi[j] = phi[j]/i*(i-1);
             }
        }
}
int main()
{
      int p;
      getPhiTable(MAXN);
      while (scanf("%d", &p) !=EOF)
      {
             printf("%d\n",phi[p-1]);
       }
      return 0;
}

      (3)採用歐拉篩求歐拉函數。

#include <stdio.h>#include <string.h>#define MAXN 65536int phi[MAXN];int prime[MAXN], pNum;bool vis[MAXN];void getPhiTable(int n) // 求2~n的歐拉函數值phi[i] (1<i<=n){      int i,j;      memset(vis,true,sizeof(vis));      pNum=0;      phi[1] = 1;      for (i = 2; i < MAXN; i++)      {             if (vis[i])                         // i是素數             {                     prime[pNum++] = i;                     phi[i] = i-1;             }             for (j = 0; j < pNum && prime[j]*i <MAXN; j++ )             {                    vis[prime[j]*i] = false;                    if (i % prime[j] == 0)                    {                          phi[i*prime[j]] = phi[i] * prime[j];                          break;                    }                    else                           phi[i*prime[j]] = phi[i] *(prime[j] - 1);              }      }}int main(){      int p;      getPhiTable(MAXN);      while (scanf("%d", &p) !=EOF)       {            printf("%d\n",phi[p-1]);       }       return 0;}

相關文章
相關標籤/搜索