好久不见,我的代码!
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool isPrime[100000010]; //isPrime[i]==1 则i是素数
int Prime[6000010],cnt=0; //用Prime这个数组存素数
void GetPrime(int n) //筛到n这个范围
{
memset(isPrime,1,sizeof(isPrime)); //初始化,每个数均为素数
isPrime[1]=0; //1不是素数
for(int i=2;i<=n;i++)
{
if(isPrime[i]) //没被筛掉仍存在
Prime[++cnt]=i; //证明i是素数,存到数组里面
for(int j=1;j<=cnt&&i*Prime[j]<=n;j++) //进入循环开始筛合数
{
isPrime[i*Prime[j]]=0;
if(i%Prime[j]==0)
break;
}
}
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
GetPrime(n);
while(q--)
{
int k;
scanf("%d",&k);
cout<<Prime[k]<<'\n';
}
return 0;
}
https://vjudge.net/problem/%E6%B4%9B%E8%B0%B7-P3383
重复筛的原则是这个合数只会被它的最小质因数筛
模拟一下筛的过程:从 2 开始,2 加入 prime 数组,再从小到大枚举质数(现在只有 2),筛掉质数与 2 的乘积(4 被筛掉)。
到了 3,3加入 prime 数组,从小到大枚举质数(此时有 2,3),筛掉质数与 3 的乘积(6,9 被筛掉)。 到了 4,4 没加入 prime 数组,枚举质数(有2,3),筛掉 8 后,因为 4 mod 2=0,触发退出条件。(不触发,就会筛掉 12,而 12=2×2×312=2×2×3,又会被 2 和 6筛一次)
有点难理解,可以先记住模板,慢慢就理解了。
就酱紫,挥挥~