素数筛

1.朴素筛法O(nlogn)

void get_primes(int n){
    for(int i = 2;i <= n; ++i){
        if(!st[i]){
            prime[cnt++] = i;
        }
        //把i的倍数全部筛掉
        for(int j = i + i;j <= n;j += i)st[j] = true;
    }
}

2.埃氏筛法O(nloglogn)

void get_primes(int n){
    for(int i = 2;i <= n; ++i){
        if(!st[i]){
            prime[cnt++] = i;
            for(int j = i + i;j <= n;j += i)st[j] = true;
        }
    }
}
//当i为质数时,筛掉i的所有倍数
//因为当i为合数时,i的倍数一定已经被i的一个因子筛掉

3.欧拉(线性)筛法O(n)

//核心:n只会被最小质因子筛掉
void get_primes(int n){
    for(int i = 2;i <= n; ++i){
        if(!st[i]){
            prime[cnt++] = i;
        }
        //保证一个合数会且只会被它的最小质因子筛掉一次
        for(int j = 0;prime[j] <= n / i; ++j){
            st[prime[j] * i] = true;
            if(i % prime[j] == 0)break;
        }
    }
}

你可能感兴趣的:(学习收藏,C++,算法,数据结构,数论,素数,质数)