筛质数

埃氏筛法:

#include <iostream>
using namespace std;
const int N = 1e6;
int n, cnt, primes[N];
bool st[N];
void get_primes(int n)
{
    //时间复杂度:n/2 + n / 3 + ... + n / n = n(1/2 + 1/3 + ... + 1/n)调和级数 = n (lnN + c) < nlogn
    for(int i = 2;i <= n;i++)
    {
        if(!st[i])
        {
            primes[cnt++] = i;
            for(int j = i + i; j <= n; j += i) st[j] = true;
        }
    }
}
int main()
{
    cin>>n;
    get_primes(n);
    cout<<cnt<<endl;
    // for(int i = 0; i < cnt; i++)
    //     cout<<primes[i]<<" ";
}

线性筛:

#include <iostream>
using namespace std;
const int N = 1e6;
int n, cnt, primes[N];
bool st[N];
void get_primes(int n)
{
    //线性筛
    for(int i = 2;i <= n;i++)
    {
        if(!st[i]) primes[cnt++] = i;
        for(int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}
int main()
{
    cin>>n;
    get_primes(n);
    cout<<cnt<<endl;
}

合数n只会被最小的质因数筛掉

if(i % primes[j] == 0) primes[j]一定是i的最小质因子。

          primes[j]也一定是i * primes[j]的最小质因子

因为j是从小到大的,primes[j]存储的也是从小到大的质数,那么primes[j] * i也是被这个最小质因子primes[j]筛掉的。

2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26

一开始:i = 2, primes[0] = {2}, st[4]筛掉了, 当n很大的时候,n / i也会很大  4

    i = 3, primes[1] = {2,3}, st[2 * 3]筛掉了,st[3 * 3)筛掉了   6  9

    i = 4, primes[1] = {2,3}, st[2 * 4]筛掉了,  8

    i = 5, primes[2] = {2,3,5}, st[2*5],st[3*5],st[5*5]  10, 15 , 25

    i = 6, primes[2] = {2,3,5}, st[2*6]  12

    i = 7, primes[3] = {2,3,5,7}, st[2*7],st[3*7],st[5*7],st[7*7]  14、21、35、49筛掉

    i = 8, primes[3] = {2,3,5,7},st[2*8]  16

综上,当i为质数的时候,会筛掉 小于等于i的质数与i的乘积,即primes[j](j = 0-i) <= i * i的所有质数乘积都会被筛掉。

合数会被它的最小质因子筛掉,比如2的合数会全部都被2筛掉,而且只会循环primes[j] = 2的一种情况,因为i 也是 2的最小质因子,当i % 2 == 0, 就不会再循环执行判断下去。

每一个质数筛的方案都是乘以前面小于等于它的质数的到的积

当一个数等于两个质因子之和的时候,n1 * n2且n1 <= n2的时候,一定是在n2加入进来之后,通过循环遍历primes[j] * i来筛掉的,n1只会筛掉 n1 * (小于等于n1的质因子)

并且一个合数如果可以等于多种积,比如 12 = 3 * 4 = 2 * 6, 一定是通过i = 6 的时候,然后通过最小质因子2来筛掉的

筛合数的时候:是通过筛从2——到这个合数的最小质因子 的积来筛 比如9的时候,st[2 * 9] st[3 * 9]就完了。晒到它的最小质因子就结束了。

    所以无论是和合数还是质数的质因子,都一定会被它的最小质因子筛掉。

质数的筛法:2 *i、3 * i 、5 * i、7 * i ……i * i

合数的筛法:2 * i、3 * i、gcd(i,{2,3,5,7,9……})最小质因数和它本身的乘积。

猜你喜欢

转载自www.cnblogs.com/longxue1991/p/12721242.html