以前只会j += i的那种筛法,因为有重复,所以效率不是太高。而欧拉筛可以在O(n)的时间内筛出素数来,就要好用一点了。
其原理就是每个合数都可以表示为几个素数乘积的形式,这些素数当中就有一个最小的。如果每个合数都只由它们的最小的素因子来筛出来的话,就避免了重复。
for(int i = 2; i <= 10000; ++ i)
{
if(!prime[i])
{
prime[++ prime[0]] = i;
}
for(int j = 1; j <= prime[0] && prime[j] * i < 10000; ++ j)
{
prime[prime[j] * i] = 1;
if(i % prime[j] == 0)
{
break;
}
}
}
前面都还好,比较费点力理解的就是if(i % prime[j] == 0)就break这里不太好理解。
看其他大佬的解释就是假如i % prime[j] == 0,那么就可以设prime[j] * k == i,那么如果不break的话,就会继续筛i * prime[j + 1],但是i * prime[j + 1]就等于prime[j] * k * prime[j + 1],而prime[j + 1]是大于prime[j]的,所以当i == k * prime[j + 1]时,就会把它筛掉,所以就不用用prime[j + 1]来筛掉它了.
这样就避免了重复,保证了每个合数都只由它最小的素因子来筛掉它,让时间复杂度在O(n)上。