4939 尤拉函式

自為風月馬前卒發表於2017-06-30
 時間限制: 1 s
 空間限制: 1000 KB
 題目等級 : 鑽石 Diamond
 
 
 
題目描述 Description

輸入一個數n,輸出小於n且與n互素的整數個數

輸入描述 Input Description

包含多組資料,n=0時結束

測試資料組數不會很多,不必先打表後輸出

輸出描述 Output Description

一組資料一行

樣例輸入 Sample Input

364684

346

5432

11

24

0

2333333

233333333

0

233333333333333

2333333333333333333333333333333333333333333333333

 

樣例輸出 Sample Output

165120

172

2304

10

8

資料範圍及提示 Data Size & Hint

1<n<9223372036854775807

 

n尤拉函式的性質(以下性質中p為素數)
n1、φ(p)=p-1
n2、φ(i*p)=p*φ(i),i%p==0
n3、φ(i*p)=(p-1)*φ(i),i%p!=0
n
n根據以上性質可以得出尤拉函式的線性篩法。
 

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define lli long long int 
 7 using namespace std;
 8 void read(lli &n)
 9 {
10     char c='+';lli x=0;bool flag=0;
11     while(c<'0'||c>'9')
12     {c=getchar();if(c=='-')flag=1;}
13     while(c>='0'&&c<='9')
14     {x=x*10+(c-48);c=getchar();}
15     flag==1?n=-x:n=x;
16 }
17 int main()
18 {
19     lli n;lli ans;
20     while(cin>>n)
21     {
22         if(n==0)break;
23         ans=n;
24         if(n%2==0)
25         {
26             while(n%2==0)
27                 n=n/2;
28             ans=ans/2;
29         }
30         for(lli i=3;i*i<=n;i+=2)
31         {
32             if(n%i==0)
33             {
34                 while(n%i==0)    n=n/i;
35                 ans=ans/i*(i-1);
36             }
37         }
38         if(n>1)
39             ans=ans/n*(n-1);
40         cout<<ans<<endl;
41     }
42     return 0;
43 }

 

相關文章