线性筛素数

  • 普通筛法

原理:素数的倍数一定不是素数,反之合数一定等于某个素数乘另一个数

复杂度:nlglgn (n是表的范围)

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn=10000000+10;
int ispri[maxn];
int main()
{
    int n,q,num;
    ispri[1]=-1;
    cin>>n>>q;
    for(int i=2;i<=n+1;i++)
    {
        if(ispri[i]==0)ispri[i]=1;
        else continue;
        int k=2;
        while(i*k<=n)
        {
            ispri[i*k]=-1;
            k++;
        }
    }
    for(int i=1;i<=q;i++)
    {
        scanf("%d",&num);
        if(ispri[num]==-1)
            printf("No
");
        else
            printf("Yes
");
    }
    return 0;
}
  •  欧拉筛法

原理:一个合数肯定可以等于一个素数和另一个比这个素数大的数相乘

复杂度:接近O(n)

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn=10000000+10;
int is[maxn],prim[maxn];
int cnt=1;
int main()
{
    is[1]=-1;
    for(int i=2; i<maxn; i++)
    {
        if(is[i]==0)prim[cnt++]=i;
        for(int j=1; j<=cnt; j++)
        {
            if(prim[j]*i>=maxn)break;
            is[prim[j]*i]=-1;
            //if(i%prim[j]==0)break;//加快一倍左右  i*prim[j+x]可以由prim[j]*num组成,也就是将来我们会将它筛掉
        }
    }
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=q;i++)
    {
        int num;
        scanf("%d",&num);
        if(is[num]==-1)printf("No
");
        else printf("Yes
");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/carcar/p/9510608.html