關於篩素數大概有以下幾種方法
1.遍歷2–(n-1)判斷有沒有除一和其本身以外的因子。
2.加一點點技巧因爲n=n的1/2次方乘以n的1/2次方,所以若n在2-(根號n)存在因子,則在根號n–n也存在因子,所以我們只需要遍歷2–根號n就可以判斷了。
3.埃氏篩,核心思想就是打表(當前數爲素數則其倍數不爲素數)
判斷素數個數模板題
具體代碼:
#include <bits/stdc++.h>//埃氏篩
using namespace std;
#define int long long
bool A[100000000];//可能是因爲洛谷數據太小的原因吧,才能過。。
signed main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin>>n; int e=n; e--;//將去1的可能(1不是質數)
for(int i=2;i*i<=n;i++){//利用開根的思想排查
if(A[i]==false){
for(int j=i*2;j<=n;j+=i){//若當前i爲素數則將他的所有倍數標記爲不是素數
if(A[j]==false){
A[j]=true; e--;
}
}
}
}
cout<<e<<endl;
}
4.歐拉篩(一種複雜度爲O(n)的打表方法)。
歐拉篩模板題
原理:如果判斷24是否爲一個素數那麼用埃氏篩的話起碼會重複篩24三次(212,38,46),那歐拉篩就是在此基礎上只篩一次就是其最小質因數與因一個合數的乘積(212).
具體代碼:
#include <bits/stdc++.h>//歐拉篩
using namespace std;
bool A[100000001]; int prime[1000001];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,m; scanf("%d %d",&n,&m);
int cnt=0;
for(int i=2;i<=n;i++){
if(A[i]==false){
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
A[i*prime[j]]=true;
if(i%prime[j]==0) break;//最重要的一步
}
}
for(int i=0;i<m;i++){
int c; scanf("%d",&c);
printf("%d\n",prime[c]);
}
return 0;
}
特別解釋一下這步:
if(i%prime[j]==0) break;//最重要的一步
若當前質因數是i的因子則爲i的最小質因數,也爲i*prime【j】的最小質因數就跳出循環.
5.Miller測試法(適用於千萬級別以上的素數判斷)