埃式筛与欧拉筛
埃式筛 时间复杂度 O(n*lglgn).
核心思想:每个质数的倍数都是合数,当发现一个质数时就将其的倍数都变成合数。
缺点:有的合数会被它的几个质因子重复筛掉,造成了时间上的浪费。
#include<iostream>
#include<cmath>
using namespace std;
int n, q, cnt, k;
bool isprime[100000005];
int sushu[1000005];
void ai(int n)
{
for(long long i=2;i<=n;i++)//由于i*i会爆int,所以就将i和j变成长整型。
{
if(!isprime[i]) {
sushu[++cnt] = i;//素数表存储。
for(long long j=i*i;j<=n;j+=i){//j从i*i开始可以减少时间的浪费但无法杜绝。
isprime[j] = true;
}
}
}
return ;
}
int main()
{
cin >> n >> q;
ai(n);
for(int i=1;i<=q;i++)
{
scanf("%d", &k);
printf("%d\n", sushu[k]);
}
return 0;
}
欧拉筛(线性筛)时间复杂度 O(n)
核心思想:与埃式筛整体大同,但却能保证每个合数都能被他最大或最小的质因子筛去,从而将时间缩到最短。
#include<iostream>
using namespace std;
int n, q, cnt, k;
bool isprime[100000005];
int sushu[10005];
void ola(int n)
{
for(int i=2;i<=n;i++)
{
if(!isprime[i]){
sushu[++cnt] = i;
}
for(int j=1;j<=cnt && sushu[j]*i<=n;j++)
{
isprime[sushu[j]*i] = true;
if(i%sushu[j]==0) break;
}
}
return ;
}
int main()
{
cin >> n >> q;
ola(n);
for(int i=1;i<=q;i++)
{
scanf("%d", &k);
printf("%d\n", sushu[k]);
}
return 0;
}
模板题来源 洛谷P3383