1. 程式人生 > 其它 >求1-n中與n互素的個數

求1-n中與n互素的個數

一、第一種求法

  思路:列舉1-n之間的數,判斷n,i的最大公約數是否為1,為1則與n互素

  程式碼實現:

 1 #include <iostream>
 2 #include <queue>
 3 #include <vector>
 4 #include <cstring>
 5 #include <string>
 6 #include <map>
 7 #include <cmath>
 8 #include <algorithm>
 9 #include <set>
10 #include <stack>
11
#include <cstdio> 12 #include <climits> 13 #define PII pair<int,int> 14 #define rep(i,z,n) for(int i = z;i <= n; i++) 15 #define per(i,n,z) for(int i = n;i >= z; i--) 16 #define ll long long 17 #define db double 18 #define vi vector<int> 19 #define debug(x) cerr << "!!!" << x << endl; 20
using namespace std; 21 inline ll read() 22 { 23 ll s,r; 24 r = 1; 25 s = 0; 26 char ch = getchar(); 27 while(ch < '0' || ch > '9'){ 28 if(ch == '-') 29 r = -1; 30 ch = getchar(); 31 } 32 while(ch >= '0' && ch <= '9'){ 33 s = (s << 1
) + (s << 3) + (ch ^ 48); 34 ch = getchar(); 35 } 36 return s * r; 37 } 38 inline void write(ll x) 39 { 40 if(x < 0) putchar('-'),x = -x; 41 if(x > 9) write(x / 10); 42 putchar(x % 10 + '0'); 43 } 44 ll gcd(int a,int b) 45 { 46 if(!b) return a; 47 return gcd(b,a % b); 48 } 49 void solve(ll n) 50 { 51 int cnt = 0; 52 for(int i = 1;i < n;i++) 53 if(gcd(n,i) == 1){ 54 cout << i << endl; 55 cnt++; 56 } 57 cout << cnt << endl; 58 } 59 int main() 60 { 61 ll n; 62 n = read(); 63 solve(n); 64 return 0; 65 }

 

二、第二種求法

  採用尤拉函式求解,由尤拉函式的性質可得1-n中與n互素的個數為n*(1-1/pi)*(1-p(i+1))...... (pi為n的素因子)

  有了這個公式,我們便只需要判斷這個數是否是素數,是否為n的因子,然後進行相乘操作即可。

  程式碼實現:

 1 #include <iostream>
 2 #include <queue>
 3 #include <vector>
 4 #include <cstring>
 5 #include <string>
 6 #include <map>
 7 #include <cmath>
 8 #include <algorithm>
 9 #include <set>
10 #include <stack>
11 #include <cstdio>
12 #include <climits>
13 #define PII pair<int,int>
14 #define rep(i,z,n) for(int i = z;i <= n; i++)
15 #define per(i,n,z) for(int i = n;i >= z; i--)
16 #define ll long long
17 #define db double
18 #define vi vector<int>
19 #define debug(x) cerr << "!!!" << x << endl;
20 using namespace std;
21 inline ll read()
22 {
23     ll s,r;
24     r = 1;
25     s = 0;
26     char ch = getchar();
27     while(ch < '0' || ch > '9'){
28         if(ch == '-')
29             r = -1;
30         ch = getchar();
31     }
32     while(ch >= '0' && ch <= '9'){
33         s = (s << 1) + (s << 3) + (ch ^ 48);
34         ch = getchar();
35     }
36     return s * r;
37 }
38 inline void write(ll x)
39 {
40     if(x < 0) putchar('-'),x = -x;
41     if(x > 9) write(x / 10);
42     putchar(x % 10 + '0');
43 }
44 bool isprime(int k)
45 {
46     for(int i = 2;i <= sqrt(k);i++)
47         if(k % i == 0)
48             return false;
49     return true;
50 }
51 void solve(ll n)
52 {
53     double cnt = n;
54     for(int i = 2;i <= sqrt(n);i++)
55         if(isprime(i) && n % i == 0){
56             cnt = cnt * (1 - 1.0 / i);
57             cout << cnt << endl;
58         }
59     cout << cnt << endl;
60 }
61 int main()
62 {
63     ll n;
64     n = read();
65     solve(n);
66     return 0;
67 }

 

收穫還是挺多的,學了個尤拉函式公式