素数筛

基础知识

1.素数(质数)

素数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。(prime number)

2.性质
(待填)

3.基本判断思路

在一般领域,对正整数n,如果用2到 sqrt(n)之间的所有整数去除,均无法整除,则n为质数

素数筛

1.暴力

按照基本判断思路暴力,可以完成筛选。

时间复杂度O(n*sqrt(n))

 

 

bool isprime(int x){
    for (int i = 2; i <= x / i; i++){
        if(x % i == 0)
            return false;
    }
    if(x < 2)return false;
    return true;
}

 

 

2.埃氏筛(一般筛、埃拉托斯特尼筛法)

时间复杂度O(nloglogn)

原理:素数的倍数都为合数

对于从2开始的每一个素数,都要扫一遍倍数,缺点是很多数被重复判断,显然不必要,由此引出欧拉筛法

 

const int MA = 1e5+5;
bool book[MA];//
int pri[MA];//存素数 
int cnt = -1;

void prime(){
    memset(book, true, sizeof(book));
    book[0] = false , book[1] = false;
    for(int i=2;i<=MA;i++){            //改进:i*i <= MA 
        if(book[i]){
            pri[++cnt] = i;
            for(int j = i + i ; j <= MA ; j += i){
                book[j] = false;
            }
        }
    }
}

 

3.欧拉筛(线性筛)

原理:每一个合数都由它最小的质因数筛去

因为prime[]数组存质数,且是递增

A. i % primes[j] == 0 ,primes[j] 一定是 i的最小质因子,也一定是primes[j]*i的最小质因子

B. i%primes[j] != 0 ,primes[j] 一定 < i的最小质因子 ,因此prime[j]一定是primes[j]*i的最小质因子

结合A,B ,<= j 时,prime[j]一定是primes[j]*i的最小质因子,筛去就好了;

      但是对于primes[j+1],prime[j+1]就不是prime[j+1]*i的最小质因数了,因为存在比primes[j+1]更小的质因子,break;

证明:

因为(i%primes[j]==0) 所以 i = k * prime[j];

i * prime[j + 1] = k * prime[j] * prime[j+1]

= k' * prime[j];

prime[j] < prime[j+1]

则 k' > i;

则 对于 i * prime[j+1] 来说,primes[j+1]不是primes[j+1]*i的最小质因数,后面也一样,break;

 

const int MA = 1e5+5;
bool book[MA];//
int pri[MA+5];//存素数 
int cnt = 0;

void prime(){
    memset(book,true,sizeof(book));
    book[0] = false, book[1] = false;
    for(int i = 2 ; i <= MA ; i++){
        if(book[i])
            pri[cnt++] = i;
        for(int j = 0 ; j < cnt && pri[j] * i <= MA ; j++){
            book[pri[j] * i] = false;
            if(i % pri[j] == 0)        //关键 
                break;
        }
    }
}

 

posted @ 2020-06-20 22:20  w_w_t  阅读(176)  评论(0编辑  收藏  举报