欧拉筛解释(含C++代码)

int prime[MAXN];//质数列表
bool isPrime[MAXN];//标记是否为质数(0表示是,1表示不是)
int cnt;//prime表长

/*
对于任意合数m,可写作m=p*k(p为m的最小质因子,k为m/p,m、k>1且为整数,k>p(p为最小质因子,k为其它几个质因子相乘,每个质因子都比p大,所以k>p))
*/

//欧拉筛(使每个合数只被其最小质因数筛去,O(n))
void Euler(int n){
    //对于每一个质数p,都一定能枚举倒k*p(因为k>p,外层循环i逐个枚举),所以所有质数m均会被筛掉
    for(int i = 2;i <= n;i++){//枚举k,k=i
        if(!isPrime[i]) prime[++cnt] = i;//如果不是质数,则存入prime数组
        for(int j = 1;j <= cnt;j++){//枚举p,p=prime[j]
            if(prime[j] * i > n) break;//超出n则不需要计算
            isPrime[prime[j] * i] = 1;//标记合数(i从2开始,所以i,prime[j]都大于1)
            if(i % prime[j] == 0) break;
            /*如果i % prime[j] == 0,则i=prime[j] * k(k为整数),记此时的j为t
            对于i * prime[j],均可写为prime[t] * k * prime[j]
            若j < t,则prime[j] < prime[t](质数表是按升序存的(2~n),所以越靠后越大),此时,最小质因数为prime[j]
            若j > t,则prime[j] > prime[t],此时,最小质因数为prime[t],prime[j]此时已不再是最小质因数,所以prime[j] * i应该已经被prime[t]筛去,可以直接结束循环
            */
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值