聪明人都懂第二个图中的小球表示啥

【算法杂谈】埃氏素数筛

【今天我们来讲讲筛子】

【埃氏筛的基本思想】

简单来说就是把不大于(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;
}

 【实际应用】

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

posted @ 2016-12-02 18:28  LJX李家鑫  阅读(303)  评论(0编辑  收藏  举报