一 埃拉托斯特尼筛法(思路非常好 就是复杂度有点高 )( o(nlognlogn) )
原理 质数的倍数不是质数 一个数不是比他小的数(1除外)的倍数这个数是质数。
2是质数 4,6,8,10....不是质数(打个标记)
3是质数(没有被标记) ,6,9,....不是质数(同样打标记)
4不是质数(被标记)
5是质数(没有被标记) 5.10......不是质数(标记)
这样递推下去 就可以得到所有质数
******推荐找1e5内的所有质数 太大了复杂度就太高了
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; bool prime[maxn]; int p[maxn]; vector<int> vs; void findprime() { for(int i = 2; i < maxn; i ++) prime[i] = true; for(int i = 2; i < maxn; i ++){ if(prime[i]) { vs.push_back(i); for(int j = i*2; j < maxn; j += i) { prime[j] = false; } } } } int main() { findprime(); cout<<vs.size()<<endl; }
其实在找的时候大多数都重复了 例如10 在2的时候标记了 在5的时候也标记了 其实5去标记其他数的时候可以从 5*5开始 (注意1e5时候i*i会爆int)
#include<bits/stdc++.h>
#define int long long using namespace std; const int maxn=1e5+5; bool prime[maxn]; int p[maxn]; vector<int> vs; void findprime() { for(int i = 2; i < maxn; i ++) prime[i] = true; for(int i = 2; i < maxn; i ++){ if(prime[i]) { vs.push_back(i); for(int j = i*i; j <maxn; j += i) { prime[j] = false; } } } } int32_t main() { findprime(); cout<<vs.size()<<endl; }
二 线性筛
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; bool prime[maxn]; int p[maxn]; int tot; vector<int> vs; void findprime() { for(int i = 2; i < maxn; i ++) prime[i] = true; for(int i = 2; i < maxn; i ++) { if(prime[i]) p[++tot]=i,vs.push_back(i); for(int j=1;j<=tot && i*p[j]<maxn; j++) { prime[i*p[j]]=false; if(i%p[j]== 0) break; } } } int main() { findprime(); cout<<vs.size()<<endl; }