欧拉筛

以前只会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)上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值