一,简介:欧拉筛法是一种线性筛,是筛选素数的高效方法(不重复筛选),合数都被最小素因子筛去
其实埃氏筛和欧拉筛都是围绕一句话:素数的倍数不是素数
那么我们可以用一个素数来循环乘以一个区间的数,那么这个结果就一定是一个合数(非质数),用一个数组来标记这个合数,就这样不断的循环筛去合数,剩下的就是素数
下表中,被标记为false的数就是素数,标记为true的数为合数
#include<stdio.h> //素数欧拉筛
#include<iostream>
#define MAX 10000
using namespace std;
int check[MAX]; //用来标记是否为合数
int prime[MAX]; //用来存储素数
int tot = 0;
void euler(){
for(int i = 2; i <= MAX; ++i){
if(!check[i]){ //如果不是合数就存入prime数组中
prime[++tot] = i;
}
for(int j = 1; j <= tot && i * prime[j] <= MAX; ++j){
check[i * prime[j]] = 1; //用这个区间的数循环遍历乘以素数,结果标为合数
if(i % prime[j] == 0)
break;
}
}
}
int main()
{
euler();
for(int i = 1; i <= tot; ++i)
printf("%d\n", prime[i]);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
#define fi first
#define se second
#define PII pair<int,int>
const int inf=1e18;
const int N=1e8+5;
int vis[N];
int n,q;
vector<int> s;
void pd(int n){
for(int i=2;i<=n;i++){
if(!vis[i])
s.push_back(i);
for(int j=0;j<s.size()&&i*s[j]<=n;j++){
vis[i*s[j]]=1;
if(i%s[j]==0) break;
}
}
}
void solve(){
cin>>n>>q;
pd(n);
while(q--){
int x;cin>>x;
cout<<s[x-1]<<"\n";
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
//cout<<fixed<<setprecision(12);
int T=1;
//cin>>T;
while(T--)
solve();
}