0
点赞
收藏
分享

微信扫一扫

三种方法筛质数,再学不会来打我 (朴素筛、埃式筛、线性筛)

发个爽文引流一下


文章目录

  • ​​Question​​
  • ​​Ideas​​
  • ​​Code​​

Question

给定一个正整数 n,请你求出 1∼n 中质数的个数。

输入格式
共一行,包含整数 n。

输出格式
共一行,包含一个整数,表示 1∼n 中质数的个数。

数据范围
1≤n≤106
输入样例:
8
输出样例:
4

Ideas

三种方法,再学不会来打我

Code

N = int(1e6+10)
primes = [0 for i in range(N)]
st = [0 for i in range(N)] # 0代表未被筛过 1代表筛过

# 朴素筛法 i从2遍历到n,筛掉所有i的倍数 O(NlogN)
def get_prime_simple(n):
cnt = 0 # 质数下标
for i in range(2,n+1):
if not st[i]:
primes[cnt] = i
cnt += 1
for j in range(i,n+1,i): # 不管是合数还是质数,都用来筛掉后面它的倍数
st[j] = 1
return cnt
# 埃式筛法 跟朴素筛法差不多时间复杂度略小 O(nloglogn)
def get_prime_ai(n):
cnt = 0 # 质数下标
for i in range(2,n+1):
if not st[i]:
primes[cnt] = i
cnt += 1
for j in range(i,n+1,i): # 只用质数筛掉后面的倍数
st[j] = 1
return cnt

# 线性筛 O(N)
def get_prime_line(n):
cnt = 0
for i in range(2,n+1):
if not st[i]:
primes[cnt] = i
cnt += 1
j = 0
while primes[j]*i <= n:
st[primes[j]*i] = 1 # 每个数一定是被他的最小质因子筛掉
if i%primes[j] == 0:
break
j += 1
return cnt


if __name__ == '__main__':
n = int(input())
cnt = get_prime_line(n)
print(cnt)


举报

相关推荐

0 条评论