筛素数的方法

今天,我们来介绍三种筛素数的方法:

1、暴力枚举法

复杂度为O(n*sqrt(n))

关键代码:

int ans[Maxn],tot;
bool isprime(int x){
    for(int i=2;i*i<=x;i++)
        if(x%i==0)
            return 0;
    return 1;
}

for(int i=2;i<=n;i++)
    if(isprime(i))
        ans[tot++]=i;
        

Tips:

经研究,除2、3外质数只能是6n+1,6n-1.因为6n+2、6n+4、6n为2的倍数,6n+3为三的倍数。

优化代码:

int ans[Maxn],tot;
bool isprime(int x){
    for(int i=2;i*i<=x;i++)
        if(x%i==0)
            return 0;
    return 1;
}

for(int i=2;i<=n;i++)
    if(i%6==1||i%6==5)
        if(isprime(i))
            ans[tot++]=i;
        

2、埃氏筛法

每次用未被删除的质数乘1、2、3……知道边界,复杂度为O(nloglogn)

关键代码:

bool prime[Maxn];
void Prime(int n){
    for(int i=0;i<=n;i++)
		prime[i]=1;
    prime[0]=prime[1]=0;
    for(int i=2;i*i<=n;i++)
        if(prime[i])
            for(int j=i*i;j<=n;j+=i)
                prime[j]=0;
} 

这里有一个小优化,如上,j从i*i出发,因为i*i以下的已被删除了

但是,一个合数可能会被删去多次,如60会被2、3、5同时删去

3、欧拉筛法(线性筛法)

优化埃氏筛法,使得每个质数只删去一次,空间复杂度提高,时间复杂度为O(n)

关键代码:

int ans[Maxn],cnt;
bool prime[Maxn];	
void Prime(int n){
	for(int i=2;i<=n;i++){
		if(!prime[i])
			ans[++cnt]=i;
		for(int j=1;j<=cnt&&i*ans[j]<=n;j++){
			prime[i*ans[j]]=1;
			if(!(i%ans[j]))
				break;
		}
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值