关于筛素数大概有以下几种方法
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测试法(适用于千万级别以上的素数判断)