• 【线性求质数】【最小质因数】浅析欧拉筛



    欧拉筛

    【算法简介】

      由于每个大于等于2的合数必定存在一个最小的质因数,所以只要筛去每个质数的倍数就相当于筛去了所有合数。但欧拉筛相比埃氏筛最大的优化就在于欧拉筛保证每个合数只被筛了一次,且是被其最小的质因数筛去的,所以欧拉筛的时间复杂度可以达到O(N)

      而如何保证每个合数都只被最小质因数筛去呢?让我们先来看一看欧拉筛的实现(第一次用python写博客,代码习惯不太好请见谅)

     1 n = input()
     2 Del = [0] * (n + 1)
     3 prime = []
     4 for a in range(2,n + 1):
     5     if Del[a] == 0:
     6         prime.append(a)
     7     for b in prime:
     8         if a * b > n: break
     9         Del[a * b] = 1
    10         if a % b == 0: break
    11 print prime

      算法其他部分和埃氏筛思路类似,在此就不再赘述。而核心就在于这句

    if a % b == 0: break

      当a % b == 0时,b为a的一个质因子,所以a = K * b。令K = a / b,则用质数数组的接下来某个质数b'去筛a * b'的时候,a * b' == K * b * b',因而b和b'都是a * b'的质因子。由于b < b',故a * b'的最小质因数是b而不是b'。如果不break就会用非最小质因数b'筛完之后,再当a' == K * b'时用b又筛一遍,提高了复杂度。所以当a % b == 0时,后续的a * b'只需让循环中接下来的某一个a' == (a / b) * b'时用b筛掉即可,既保证了每个数都被其最小质因数筛去,也保证了每个数都只被筛一次。

    【利用欧拉筛求最小质因数】

      根据【算法简介】中的介绍,每个非质数都被其最小质因数筛去,所以只要在被筛去的时候记录一下被哪个质数筛去,这样就的到了最小质因数,相当于是欧拉筛的“副产品”。python实现如下:

    n = input("")
    Del = [0] * (n + 1)
    Son = [0] * (n + 1)
    prime = []
    for a in range(2,n + 1):
    	if Del[a] == 0:
    		prime.append(a)
    		Son[a] = a
    	for b in prime:
    		if a * b > n: break
    		Del[a * b] = 1
    		Son[a * b] = b
    		if a % b == 0: break
    print prime;
    for a in range(2,n + 1):
    	print a,"->",Son[a];
    
  • 相关阅读:
    (转)描述线程与进程的区别?
    Python学习笔记:ceil、floor、round、int取整
    Python学习笔记:SQL中group_concat分组合并操作实现
    Python学习笔记:pd.rank排序
    函数声明
    Dictionary 介绍
    Tuple介绍
    List介绍
    DataGridView 如何退出 编辑状态
    C#实现打印与打印预览功能
  • 原文地址:https://www.cnblogs.com/reddest/p/9803268.html
Copyright © 2020-2023  润新知