线性筛
闲来无事,把洛谷上的弄过来吧
:“为什么叫线性筛?”
(gym)“因为它复杂度是O(n)的。”
:“为啥它复杂度是O(n)的就叫线性筛?”
……机房沉默……
————————————一条阔爱滴分割线————————————————
1.开根
点击查看代码
#include<iostream> //开根法
#include<bits/stdc++.h>
#define maxn 2100010
using namespace std;
bool g(int x){
if(x<2) return false;
for(int i=2;i<=sqrt(x);i++){
if(x%i==0) return false;
}
return true;
}
int n,a[maxn];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
if(g(a[i])) cout<<a[i]<<" ";
}
return 0;
}
开根法的话,就不用解释了吧……
2.埃氏筛
埃氏筛就是把不是素数的找出来,把倍数都排除了。
点击查看代码
#include<iostream> //埃氏筛
#include<bits/stdc++.h>
#define maxn 2100010
using namespace std;
int n,t;
bool vis[maxn];
void era(int tt){
for(int i=2;i<=tt;i++){
if(vis[i]) continue;//如果已经被标记,继续就好了
for(int j=i*2;j<=tt;j+=i){ //把i的倍数标记一遍,他都倍数了还怎么可能是质数。。
vis[j]=1; //标记
}
}
}
int main(){
cin>>n;
vis[0]=1,vis[1]=1;
era(100001);
for(int i=1;i<=n;i++){
cin>>t;
if(!vis[t]){
cout<<t<<" ";
}
}
return 0;
}
3.欧拉筛
点击查看代码
#include<iostream> //欧拉筛 较优,时间复杂度较小
#include<bits/stdc++.h>
#define maxn 2100010
using namespace std;
int f[maxn],vis[maxn],cnt,n,t;
void prime(int tt){
for(int i=2;i<=tt;i++){
if(!vis[i]) {
f[++cnt]=i; //把质数存进去
}
for(int j=1;j<=cnt;j++){ //把每个质数的倍数标记成不是质数
if(f[j]*i>tt) break; //判断越界
vis[f[j]*i]=1; //标记
if(i%f[j]==0) break; //这里是如果在上面那个循环里遍历到的数已经是存进去的质数的倍数了,那我们就没必要重复进行了
}
}
}
int main(){
cin>>n;
vis[0]=1;
vis[1]=1;
prime(100001);
for(int i=1;i<=n;i++){
cin>>t;
if(!vis[t]){
cout<<t<<" ";
}
}
return 0;
}
因为欧拉筛要取%,所以在数据较小时,埃氏筛是最快的。
欧拉筛……和埃氏筛差不多,只是多了几个判断条件。
- 当然埃氏筛和欧拉筛中的判断数组里的0和1都要标记成不是质数哦!