ETH官方钱包

創作內容

1 GP

線性篩法 (不專業講解)

作者:瘋頭是笨蛋│2021-04-27 23:39:23│巴幣:5│人氣:445
寫某cf題,我想要在最快的時間建出
每個數包含哪些質因數
然後我就回去看我很久以前抄別人 C++ 的 code
我一直都搞不太懂線篩原理
於是花了幾秒的時間理解一下
希望我打完這邊能喇出我想要的東西
<鬼之hr分隔線>

一般大家印象中的篩法
是用質數的 n 倍去篩出合數
這樣會有重複篩選的問題
例如 2*15 = 3*10 = 5*6 = 30
但如果這個表示法的特性
每個數就只會被篩到一次而已

先上 python 的線篩 code
from time import time
time1 = time()
N = int(1e5)
is_prime = [True] * (N + 1)  # have 0
is_prime[0] = is_prime[1] = False
prime = []
for n in range(2, N + 1):
    if is_prime[n]:
        prime.append(n)
    for p in prime:
        if p * n > N:  # Index out of range
            break
        is_prime[p * n] = False
        print("%d*%d = %d" % (p, n, p * n))
        if n % p == 0:
            break
print(prime)
print(time() - time1)
以下不專業講解...
首先,對於每個合數 a
則 a 恰有一個唯一的表示法 p * n
且 p 為 a 的最小質因數,以及 p ≤ n
顯然說到最小的質因數 肯定是唯一的
這部分理解上應該沒有什麼大問題

我們先無視最後的那個 break
首先先要證明這能正確地篩掉所有合數
由於 ≤ n 的所有質數都會被迭代到
當我們也迭代所有的 n 值
則這就是所有 p ≤ n 的組合

再來要搞清出為什麼那邊可以 break
這個 break 會導致 > 某個 p 的質數不會跟 n 一起篩
但此時這個 p 也是 n 的質因數
所以其實你會發現,那些原本要被篩的數
它也會包含 p 這個質因數
那它的表示法的最小質因數也應該 ≤ p 吧
喔 所以我們 break 掉,就因為之後篩的數
就不是用那個表示法篩掉的,漂亮! (Wa thinking...)

現在只剩一個問題 複雜度
到這邊我們已經能保證我們沒有重複篩數
因此 複雜度也是漂亮的 O(n)

Wa thinking...
以下開放電神炮我...

引用網址:http://www.jamesdambrosio.com/TrackBack.php?sn=5134077
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:python|篩法

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

1喜歡★terryobeyes 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:cf #697(Div.... 後一篇:cf #717(Div....


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情? 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】