素数

1. 普通筛........

2. 埃氏筛

  算术基本定理(正整数唯一分解定理)应用

  复杂度 听说是O(nloglogn) 听说证明挺鬼畜

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int MAXN = 11111111;
 5 bool isPrime[MAXN];
 6 
 7 int main(){
 8     //freopen("test.txt", "w", stdout);
 9     memset(isPrime, true, sizeof(isPrime));
10     int x = 0, k = ceil(sqrt(MAXN));
11     for(int i = 2; i < k; ++i){
12         if(isPrime[i])
13             for(int j = i; i * j < MAXN; ++j)
14                 isPrime[i*j] = false;
15     }
16     for(int i = 2; i < MAXN; ++i) 
17         if(isPrime[i])
18             printf("%d ", i);
19     return 0;
20 }

3. 欧拉筛

  还是跟埃氏筛一样用算术基本定理

  但是埃氏筛对于某些数会多次筛除

  欧拉筛使合数只被其最小质因数筛除  时间复杂度为 O(n)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int MAXN = 11111111;
 5 int prime[MAXN];
 6 bool isPrime[MAXN];
 7 
 8 int main(){
 9     //freopen("book.txt", "w", stdout);
10     memset(isPrime, true, sizeof(isPrime));
11     int x = 0;
12     for(int i = 2; i < MAXN; ++i){
13         if(isPrime[i]) prime[x++] = i;
14         for(int j = 0; j < x; ++j){
15             if(i * prime[j] >= MAXN) break;
16             isPrime[i*prime[j]] = false;
17             if(i % prime[j] == 0) break;
18         }
19     }
20     for(int i = 0; i < x; ++i) printf("%d ", prime[i]);
21     return 0;
22 }

精髓是 if(i % prime[j] == 0) break; 

当某个数能被某质数整除时,后面的这个数的倍数的最小质因子一定是当前的质数而不是其他的质数,所以退出循环

例如: 当 i == 6 时筛去(6 * 2 = )12后,6被2整除,说明6*3、6*5的最小质因数是2,而不是3和5

4.Miller_rabin强伪素数测试

Int64以内Rabin-Miller强伪素数测试 和Pollard 因数分解的算法实现

 1 typedef long long ll;
 2 ll mul_mod(ll a, ll b, ll m){
 3     ll ans = 0, exp = a;
 4     while(exp >= m) exp -= m;
 5     while(b){
 6         if(b & 1){
 7             ans += exp;
 8             while(ans >= m) ans -= m;
 9         }
10         exp += exp;
11         while(exp >= m) exp -= m;
12         b >>= 1;
13     }
14     return ans;
15 }
16 ll pow_mod(ll x, ll n, ll m){
17     ll ans = 1, exp = x;
18     while(exp >= m) exp -= m;
19     while(n){
20         if(n & 1) ans = mul_mod(ans, exp, m);
21         exp = mul_mod(exp, exp, m);
22         n >>= 1;
23     }
24     return ans;
25 }
26 bool miller_rabin(ll n){
27     if(n < 2) return false;
28     if(n == 2) return true;
29     if(!(n & 1)) return false;
30     ll p = n - 1;
31     int k = 0;
32     while(!(p & 1)){
33         ++k;
34         p >>= 1;
35     }
36     for(int i = 0; i < 20; ++i){
37         ll a = rand() % (n - 1) + 1;
38         ll x = pow_mod(a, p, n);
39         if(x == 1) continue;
40         bool flag = false;
41         for(int j = 0; j < k; ++j){
42             if(x == n - 1){
43                 flag = true;
44                 break;
45             }
46             x = mul_mod(x, x, n);
47         }
48         if(flag) continue;
49         return false;
50     }
51     return true;
52 }

附:POJ 2429 代码

  1 #include <map>
  2 #include <vector>
  3 #include <iostream>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 typedef long long ll;
  8 
  9 ll mul_mod(ll a, ll b, ll mod){
 10     ll ans = 0, exp = a;
 11     while(exp >= mod) exp -= mod;
 12     while(b){
 13         if(b & 1){
 14             ans += exp;
 15             if(ans >= mod) ans -= mod;
 16         }
 17         exp <<= 1;
 18         if(exp >= mod) exp -= mod;
 19         b >>= 1;
 20     }
 21     return ans;
 22 }
 23 ll pow_mod(ll x, ll n, ll mod){
 24     ll ans = 1, exp = x;
 25     while(exp >= mod) exp -= mod;
 26     while(n){
 27         if(n & 1) ans = mul_mod(ans, exp, mod);
 28         exp = mul_mod(exp, exp, mod);
 29         n >>= 1;
 30     }
 31     return ans;
 32 }
 33 
 34 const int MP = 233333;
 35 vector<int> primes;
 36 vector<bool> isprime;
 37 void init_primes(){
 38     isprime = vector<bool>(MP, true);
 39     isprime[0] = isprime[1] = false;
 40     for(int i = 2; i < MP; ++i){
 41         if(isprime[i]) primes.push_back(i);
 42         for(int j = 0; j < primes.size() && i * primes[j] < MP; ++j){
 43             isprime[i * primes[j]] = false;
 44             if(i % primes[j] == 0) break;
 45         }
 46     }
 47 }
 48 bool miller_rabin(ll n){
 49     if(n < 2) return false;
 50     if(n == 2) return true;
 51     if(!(n & 1)) return false;
 52     ll p = n - 1;
 53     int k = 0;
 54     while(!(p & 1)){
 55         ++k;
 56         p >>= 1;
 57     }
 58     for(int i = 0; i < 20; ++i){
 59         ll a = rand() % (n - 1) + 1;
 60         ll x = pow_mod(a, p, n);
 61         if(x == 1) continue;
 62         bool flag = false;
 63         for(int j = 0; j < k; ++j){
 64             if(x == n - 1){
 65                 flag = true;
 66                 break;
 67             }
 68             x = mul_mod(x, x, n);
 69         }
 70         if(flag) continue;
 71         return false;
 72     }
 73     return true;
 74 }
 75 bool is_prime(ll n){
 76     if(n < MP) return isprime[n];
 77     else return miller_rabin(n);
 78 }
 79 
 80 ll pollard_rho(ll n, int a){
 81     ll x = 2, y = 2, d = 1;
 82     while(d == 1){
 83         x = mul_mod(x, x, n) + a;
 84         y = mul_mod(y, y, n) + a;
 85         y = mul_mod(y, y, n) + a;
 86         if(x == y) break;
 87         d = __gcd((x >= y ? x - y : y - x), n);
 88     }
 89     if(d == 1 || d == n) return pollard_rho(n, a + 1);
 90     return d;
 91 }
 92 void factorize(ll n, map<ll, int>& factors){
 93     if(is_prime(n)) ++factors[n];
 94     else{
 95         for(int i = 0; i < primes.size(); ++i)
 96             while(!(n % primes[i])){
 97                 ++factors[primes[i]];
 98                 n /= primes[i];
 99             }
100         if(n != 1){
101             if(is_prime(n)) ++factors[n];
102             else{
103                 ll d = pollard_rho(n, 1);
104                 factorize(d, factors);
105                 factorize(n / d, factors);
106             }
107         }
108     }
109 }
110 
111 int main(){
112     ios::sync_with_stdio(false);
113     cin.tie(0);
114     ll a, b;
115     init_primes();
116     while(cin >> a >> b){
117         ll c = b / a;
118         map<ll, int> factors;
119         factorize(c, factors);
120         vector<ll> p_factors;
121         for(map<ll, int>::iterator it = factors.begin(); it != factors.end(); ++it){
122             ll tmp = 1;
123             while(it->second--) tmp *= it->first;
124             p_factors.push_back(tmp);
125         }
126         ll x = 1, y = c, sum = 1e18;
127         for(int i = 0; i < (1 << p_factors.size()); ++i){
128             ll tx = 1;
129             for(int j = 0; j < p_factors.size(); ++j)
130                 if(i & (1 << j))
131                     tx *= p_factors[j];
132             ll ty = c / tx;
133             if(tx < ty && tx + ty < sum){
134                 x = tx;
135                 y = ty;
136                 sum = x + y;
137             }
138         }
139         cout << x * a << " " << y * a << endl;
140     }
141     return 0;
142 }
原文地址:https://www.cnblogs.com/book-book/p/5385234.html