线性筛

首先说声抱歉,最近一直忙着调剂,没有及时更新。

今天说下素数筛的进化版——线性筛(很方便的)

上次我们说到,素数筛的缺点就是一个合数有可能会重复的去判断,如果能一次性的判断,就成为线性的的时间了。大家发现:每个合数必有一个最小素因子。每个合数仅被它的最小素因子筛去正好一次。用mark[ ]做为标记数组,用pri[ ]保存所有素数,mark[i * pri[j]] = 1这就语句,就是精华所在,即每个合数仅被它的最小素因子筛去正好一次,执行这语句时i % pri[j] == 0,pri[j]一定是pri[j] * i 的最小因子。

下面代码献上(以求100000内的素数和为例)

注:我把mark[]和pri[]定义成全局变量,是为了方便,实际中按照个人喜好便可

#include<iostream>
using namespace std;
#define MAX 100000

int pri[MAX] = {0};
int mark[MAX] = {1, 1, 0};
int index = 0;
void prime(){ //线性筛 
    int i, j;
    for(i = 2; i < MAX; i++){
        if(mark[i] == 0){
            pri[index++] = i;
        }
        for(j = 0; j < index && pri[j] * i < MAX; j++){
            mark[i * pri[j]] = 1; // 个合数仅被它的最小素因子筛去正好一次
            if(i % pri[j] == 0){ 
                break;
            }
        }
    }
    return ;
}

void putout(){ //输出MAX以内的所有素数 
    int i;
    for(i = 0; i < index; i++){
        cout << pri[i] << " ";
    }
    return ;
}

int sum(){ //求和 
    int i, pri_sum = 0;
    for(i = 0; i < index; i++){
        pri_sum += pri[i];
    }
    return pri_sum;

int main(){
    prime(); 
    //putout();
    cout << MAX <<" 以内素数和为 " << sum() << endl;
    return 0;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值