zoukankan      html  css  js  c++  java
  • 【算法杂谈】埃氏素数筛

    【今天我们来讲讲筛子】

    【埃氏筛的基本思想】

    简单来说就是把不大于(n为数据范围)以内的素数的倍数全都去掉,那么剩下的就是2~n之间的素数了。

    【举个例子】

    我们假设现在n是25。

    第一步:先把2作为筛子,那么所有2的倍数都被筛掉了。

    则当前序列为:2 3 5 7 9 11 13 15 17 19 21 23 25

    第二步:剩下的序列中第一个素数是3,将序列中3的倍数划掉。

    则当前序列为:2 3 5 7 11 13 17 19 23 25

    25仍然大于3的平方,所以我们还要继续筛

    现在序列中第一个素数是5,同样将序列中5的倍数划掉。

    则当前序列为:2 3 5 7 11 13 17 19 23

    因为23小于5的平方,跳出循环

    So 最后的答案就是:2 3 5 7 11 13 17 19 23 啦

    是不是很简单?

    哦,忘说了,这种方法的时间复杂度是O(n log n)。

    想要更快的吗,还有线性筛呢!!!

    【参考代码】

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const long long maxn=10000007+10;
    const long long maxp=700000;
    int vis[maxn];
    long long prime[maxp];
    long long n;
    
    long long gen()
    {
        long long m=(long long)sqrt(n+0.5);
        memset(vis,0,sizeof(vis));
        vis[2]=0;
        for(long long i=3;i<=m;i=i+2)
    	{
            if(!vis[i])for(long long j=i*i;j<=n;j+=i) vis[j]=1;
            if(i*i>n)break;
        }
        long long c=1;
        prime[0]=2;
        for(long long i=3;i<=n;i=i+2) if(!vis[i]) prime[c++]=i;
        return c;
    }
    int main()
    {
        long long c;
        cin>>n;
        c=gen();
        for(long long i=0;i<c;i++) printf("%lld ",prime[i]);
        cout<<endl<<c;
        return 0;
    }
    

     【实际应用】

    找素数啊,这还用说吗???

  • 相关阅读:
    博客
    参考博客
    KMP
    串匹配
    简单数论
    B
    各种常用函数的模板以及自己的测试数据
    header
    memcached的图形界面监控
    缓存策略
  • 原文地址:https://www.cnblogs.com/lijiaxin-blog-cpp/p/6126827.html
Copyright © 2011-2022 走看看