最近集训在讲数论(心累,文章应该会持续更新
正常方法应该都会吧~
bool pan(int x){
if(x<=1) return 0;
for(int i=2;i*i<=x;i++){
if(x%i==0) return 0;
}
return 1;
}
埃式筛:
主体思路:还是遍历小于n的数,除1外,如果这个数是第一次被筛到,那么他就是质数,之后我们将找到质数的小于n的倍数全部标记为不是质数!这样就可以解释为什么未被标记的的数是质数——因为小于他的质数没有可以将其质因数分解
Code
for(int i=2;i<=n;i++) p[i]=1;
for(int i=2;i<=n;i++){
if(p[i]){
for(int j=i*2;j<=n;j+=i) p[j]=0;
}
}
线性筛:
埃式筛虽然在普通方法上有所提升,但是还是有些数会被重复判断
而线性筛同样是寻找未标记的数——记为质数加入队列,同时,将i与队列中的数相乘所得到的数标记不为质数
注意:因为要保证每一个数只被筛一次,所以筛到 p[j]*i 并且 i%p[j]==0,说明下面的数可以被质因数分解为多个质数,因为线性筛只找出一个质数即可,之后会重复,所以需要跳出(牢记)
Code
#include<bits/stdc++.h>
using namespace std;
int n,p[10001000],q;
bool vis[100010000];
int main(){
scanf("%d%d",&n,&q);
int cnt=0;
for(int i=2;i<=n;i++){
if(!vis[i]) p[++cnt]=i;
for(int j=1;i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
for(int i=1;i<=q;i++){
int x;
scanf("%d",&x);
printf("%d\n",p[x]);
}
}