线性筛素数详解

竞赛中我们很多时候会涉及数论的相关知识,说到数论那就不得不提到素数了。下面我就介绍竞赛中常用的筛选素数的方法。

第一种O(sqrt(N))试除法

很简单,就是从素数的定义出发。素数只能被1和它本身整除的数(1除外),那么我们就验证2~sqrt(n)之间是否有i能都整除n即可。特殊的要验证1;

bool check(int n){
    for(int i=2;i<=sqrt(n);i++)if(n%i==0)return 0;
    return n!=1;
}

第二种就是用线性筛法筛出一个素数表了,O(n)的时间即可完成

线性筛素数如何做到线性,关键就在于它的核心思想。

根据唯一分解定理我们知道任何一个数可以用若干个素数的乘积表示,而线性筛法的核心便是使用每个数最小的那个素因数将其筛去,每个数筛一次,就能做到o(n);

void find(){
    for(int i=2;i<=n;i++){
        if(!vis[i])p[++cnt]=i;    当前数是素数,那么我们将其储存
        for(int j=1;j<=cnt&&p[j]*i<=n;j++){vis[p[j]*i]=1;if(i%p[j]==0)break;}
         依次将每个i  与小于它的素数相乘,将得到的数给筛去
         特别的,当 i%p[j]==0时退出,为什么呢,因为当前循环中  后续所有的数i*p[k](k>j)都有一个素因子p[j],那么它在后面的循环(当i=i*p[k]时)中自然会被p[j]筛去,如果现在继续筛下去,那么后续又要筛一次,那就不是线性筛了
    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值