目录

质数筛法,是一种快速“筛”出2~n之间所有质数的方法。

1.普通筛法:O(nlogn)

2.埃氏筛法:O(nloglogn)

3.线性筛法:O(n)


质数筛法,是一种快速“筛”出2~n之间所有质数的方法。

1.普通筛法:O(nlogn)

        不管是质数还是合数,都用于筛其后面的它的倍数

        缺点:一个数被反复筛去浪费了时间

void get_primes(){
    for(int i = 2; i <= n; i++){

        if(!st[i]) primes[cnt++] = i;//把质数存在primes[]数组里

        for(int j = i; j <= n; j += i){//不管是质数还是合数,都用于筛其后面的它的倍数
            st[j]=true;
        }
    }
}

2.埃氏筛法:O(nloglogn)

        只用质数就可以把后面的所有合数筛去

        优点:比起普通筛法却是节省了一些时间

        缺点:但是还是有重复筛掉一个数的操作

void get_primes(){
    for(int i = 2;i <= n;i++){
        if (st[i]) continue;
        primes[cnt++] = i;//把质数存在primes[]数组里
        for(int j = i+i;j <= n;j += i) 
		    st[j] = true;//只用质数就可以把后面的所有合数筛去
        
    }
}

3.线性筛法:O(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 ++ )
    //把primes[j] <= n / i 看成 primes[j] * i <= n
    //这样遍历到 >n 时就会自动退出,设置了边界
        {
            st[primes[j] * i] = true;//将质数倍数筛掉
            if (i % primes[j] == 0) break;
    //关键判断:
//    	1.如果i % primes[j] == 0 说明 prime[j] 是 i 的最小质因子
//    	那么如果j继续++的话primes[j + 1] > primes[j],后续被筛掉的数就不是被最小质因子筛去的
//    	假设后续被筛掉的数为m,m可以看成m = i * prime(j+1) = k * prime(j) * prime(j+1) (k = i / primes[j])
//    	2.如果i % primes[j] != 0 说明 prime[j] 不是 i 的最小质因子,也就可以继续筛了	
	
        }
    }
}
02-21 04:56