各种的筛法求质数

·一. 暴力遍历取模。(不过多解释)

微改良的是可以从2遍历到根号n。

// 用于求单个质数。

二. 埃氏筛

从二到n枚举,将枚举的每个数的倍数打上是质数的标记。把是质数的数记录到数组中。

用于求一个区间内的质素。

代码如下

const int N = 1e5 + 10;

int prime[N];

bool is_prime[N];

int p = 0;

void find(int n)

{

for(int i = 0; i <= n;i ++) is_prime[i] = true;

is_prime[0] = is_prime[1] = false;

for(int i = 2;i <= n;i ++){

if(!is_prime[i]){

prime[p ++] = i;

for(int j = i;j < n / i;j ++) is_prime[j * i] = false;//优化一下j从开始遍历
}

}

}

此方法会遇到一个非质数多次被标记的情况不是最优解。

三.线性筛

此方法可看作上一方法的上位代替解决了重复标记的问题。

代码如下

const int N = 1e5 + 10;

int prime[N], p = 0;

bool is_prime[N];

void find(int n){
for(int i = 2;i <= n;i ++){

if(!is_prime[i])prime[p ++] = i;

for(int j = 0;j < p&&prime[j]*i <= n;j ++){

is_prime[i * prime[j] = 1;

if(i%prime[j] ==  0) break;//可以如此理解所有i先将其两倍筛去,接着筛去三倍,5倍,7倍......;

反过来理解将所有数能除2二的就筛去并break,否则能除3的晒去依次类推。
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值