线筛素数进阶法

版权声明:本文为博主原创文章,未经博主允许不得转载,除非先点了赞。 https://blog.csdn.net/A_Bright_CH/article/details/82011330

对于12,在传统线筛素数法中,会被2*6,3*4,两组重复否定为合数。
我们可以规定每次只能让合数的质因数由大到小累计,如12=3*2*2,60=5*3*2*2。
实现时,我们可以开一个v数组,v[x]记录x的最小质因数,x能借助的素数只有prime[1]~prime[k](prime[k]<=v[x])。
在确定了为一方法枚举给个数后,这种方法就是O(N)了。

代码

例题:洛谷3383

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=10000010;

int n,m,cnt;
int v[maxn],prime[maxn];

void primes()
{
    cnt=0;
    memset(v,0,sizeof(v));
    for(int i=2;i<=n;i++)
    {
        if(v[i]==0)
        {
            prime[++cnt]=i;
            v[i]=i;
        }
        for(int j=1;j<=cnt;j++)
        {
            if(i*prime[j]>n || prime[j]>v[i]) break;
            v[i*prime[j]]=prime[j];
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    primes();
    while(m--)
    {
        int x;
        scanf("%d",&x);
        if(v[x]==x) puts("Yes");
        else puts("No");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/A_Bright_CH/article/details/82011330