质数及线性筛

质数与线性筛

####本文将详细将接OI中对于质数的筛法

1.基本筛法

对于一个合数 N ,一定存在一个能够整除 N 的数介于 2 - sqrt{N} 。

正确性显然,只需反证即可。
所以只需要对 2 - sqrt{N} 的数扫一遍即可

bool  simple( int  a ){
    for( int  i = 2 ; i <= sqrt(a) ; i++ )
        if( a % i == 0 ) return false ;
    return true ;
}

2. Eratosthenes筛法

这个筛法是我在初学时经常使用的,原因是既方便又好写,对于 部分水题 或者 不是以筛质数为主要目的题 的可以快速写完。
其原理大致如下

筛法执行过程
2 3 4 5 6 7 8 9 10 11  ...
T   F   F   F   F
2 3 4 5 6 7 8 9 10 11  ...
T T F   F   F F F
2 3 4 5 6 7 8 9 10 11  ...
T T F T F   F F F
2 3 4 5 6 7 8 9 10 11  ...
T T F T F T F F F
2 3 4 5 6 7 8 9 10 11  ...
T T F T F T F F F  T

我们对于从2开始的每一个数,先进行扫描,如果没有 False 标记,则表明这个数之前的所有数都无法整除它,将其加入质数表,并将其倍数都打上 False 标记 。
先上代码

int  num ,  tot , d[ maxn ] ;
bool used[ maxn ] ;

void  Eratosthenes(){
    for( int  i = 2 ; i <= num ; i++ ){
        if( !used[ i ] ){
            tot++ ;
            d[ tot ] = i ;
            for( int  j = i ; j <= num/i ; j++ )
                used[ i*j ] = true ;
        }
    }
}

int  main(){
    scanf("%d",&num);
    Eratosthenes();
    for( int  i = 1 ; i <= tot ; i ++ )
        printf("%d ", d[ i ] ) ;
    return 0 ;
}

埃氏筛的复杂度接近线性,达到了 N(N logN logN )。但是埃氏筛对部分有多个因数的数进行了多次删除,以至于可能被卡掉。所以我们有了优化后的线性筛法


3.线性筛法

既然有部分数会被多个质因子筛重复筛,那么,我们只需要让每个合数只被它的最小质因子筛一次即可。
在这里给出具体的思路和代码

#include<bits/stdc++.h>
using namespace std;

int  used[ maxn ] , p[ maxn ] , num , tot = 0 ;//  p[ ]数组用来存筛出的质数

void  Primefactor(){
    for( int  i = 2 ; i <= num ; i++ ){
        if( used[ i ] == 0 ){
            tot++ ;
            used[ i ] = i ; p[ tot ] = i ;
        }
        for( int  j = 1 ; j<= tot ; j++ ){
            if( p[ j ] > used[ i ] || p[ j ] > num/i )break ;//不要忽视边界问题
            used[ i * p[ j ] ] = p[ j ] ;  // 判定
        }
    }
}

int  main(){
    scanf( "%d",&num );
    Primefactor() ;
    for( int  i = 1 ; i <= tot ; i ++ )printf( "%d ",p[ i ] ) ;
    return 0 ;
}

转载于:https://www.cnblogs.com/ssw02/p/10458968.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值