n只会被最小质因子筛去。
O(n)
const int N=1000010;
int primes[N],res;
bool st[N];
void get_primes(int n)
{
// LOOP1
for(int i=2;i<=n;++i)
{
if(!st[i]) primes[res++]=i;
// LOOP2
for(int j=0;primes[j]<=n/i;++j)
{
st[primes[j]*i] = true;
if(i%primes[j]==0) break;
}
}
}
为了更形象地体现线性筛的线性特点,列表。(初学到时不是很理解,怎么做到线性复杂度的。。)
i | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
primes[0] = 2 | 2x2 | 2x3 | 2x4 | 2x5 | 2x6 | 2x7 |
primes[1] = 3 | 3x3 | 3x5 | 3x7 | |||
primes[2] = 5 | 5x5 | 5x7 | ||||
primes[3] = 7 | 7x7 |
根据表中的规律,可以发现线性筛法的特点 —— n只会被最小质因子筛去。
在检验过程中,
只要LOOP1
的索引i
可以被当前素数除尽时,即i%primes[j]==0
,将不再继续LOOP2
。因此LOOP2
中使用的素数总是不会超过LOOP1
的索引i
:i%primes[j]==0
,因为当前记录的最大素数即为i
,对自身取余为0。
以上约束,保证了只会出现2x6而不会出现3x4这样的组合筛去12。以及不会出现3x2这种组合情况筛去6。
赞