总结-筛素数

总结-筛素数


埃拉托斯特尼筛法


如上图所示,朴素的埃氏筛法从2~n对于每个没有被筛去的数——即素数,从该素数开始将i的各个倍数依次删去.

int not_pri[maxn],pri[maxn],pcnt;

void init_pri(int n)
{
    not_pri[0]=not_pri[1]=1;
    for(int i=2;i<=n;i++) {
        if(!not_pri[i]) pri[pcnt++]=i;
        for(int j=i*2;j<=n;j+=i) not_pri[j]=1;
    }
}

其时间复杂度为 n/2+n/3+...+n/n=O(nlogn) 

当然可以对其进行优化,对于不是素数的数,不需要对其倍数进行删去操作,而且对于每一个素数 p  开始筛的位置应该是pp 

int not_pri[maxn],pri[maxn],pcnt;

void init_pri(int n)
{
    not_pri[0]=not_pri[1]=1;
    for(int i=2;i<=n;i++) if(!not_pri[i]) {
        pri[pcnt++]=i;
        for(int j=i*i;j<=n;j+=i) not_pri[j]=1;//注意i*i可能会溢出
    }
}

时间复杂度为 O(nloglogn) 
参考/图片来源:
wikiwand 英文
wikiwand 中文


线性筛

对于任意一个合数将其拆分成最小因数和最大因数,且最小因数为素数.因为若最小因数不是素数,一定可以将其拆分成两个数相乘形式,这个数一定不是最小因数.
那么就可以用当前数和已有素数来筛,那么应该筛到什么时候.

对于一个数 N  ,有N=pM 
M  中存在p  <p ,则有 N=p  M    ,此时 M  >M  .

所以当 M%p=0  时,就应该停止继续枚举更大的 p  ,因为之后枚举的p 不能使得 M  成为pM 的最大因数.

int not_pri[maxn],pri[maxn],pcnt;

void init_pri(int n)
{
    not_pri[0]=not_pri[1]=1;
    for(int i=2;i<=n;i++) {
        if(!not_pri[i]) pri[pcnt++]=i;
        for(int j=0;j<pcnt&&pri[j]*i<=n;j++) {
            not_pri[pri[j]*i]=1;
            if(i%pri[j]==0) break;
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值