素数筛

  • 埃氏筛,时间复杂度o(n*log(log2n))

将数从2遍历,如果没有被筛掉,则说明这个数是质数,然后将质数的倍数全部筛掉

for (int i = 2; i <= n / i; i++)
    if (!pri[i])//若i未被筛掉则必定是质数
        for (int j = i * i; j <= n; j += i)//枚举i的倍数必定是合数
            pri[j] = 1;

 

  • 欧拉筛(线性筛),时间复杂度o(n)

有些数是两个质数相乘得来的,比如6,就会被筛掉两次,所以当i%p[j]==0时,跳出循环,减少筛的时间复杂度。

int cnt = 0;
for (int i = 2; i <= n; i++) {
    if (!pri[i])p[++cnt] = i;
    for (int j = 1; j <= cnt && i * p[j] <= n; j++) {
        pri[i * p[j]] = 1;//筛掉整数倍
        if (i % p[j] == 0)break;//后面会在次出现,目前不用筛
    }
}

 

posted @ 2023-07-30 20:29  DLSQS  阅读(63)  评论(0)    收藏  举报