by qw:
線性篩法最基礎的功能就是求[1,n]中的素數,以此為基礎,可以對他進行一些變形。變形後的線性
篩法可以實現許多其他的功能。(下文中的tot均指一定區間內的質數個數)
先看一道簡單的問題:求[1,n]中的m個數的最大質因子的序數(hdoj2136)
這個問題可以利用線性篩法打乙個質數表,然後二分答案,複雜度為o(n+mlog(tot))。
然而,如果m很大,演算法必然會超時。我們可以對線性篩法進行一些變形,每次篩掉乙個合數時,
可以通過他的兩個約數推出他的最大質因子。這樣可以得到乙個o(maxn+m)的演算法。
同樣的,每次篩掉乙個合數時,也可以記下他的最小質因子,這樣就可以在log(n)以內的時間內
給出乙個數的質因數分解,也就可以同時求出phi(n)的值。
再看一道問題:求出n!的質因數分解,輸出為若干行,每行第乙個數為乙個質數,第二個數為它的次
數,時間限制為兩秒。(n<=10^7)
這道題很容易想到非線性的做法,即按以上的方法篩一遍,再乙個乙個的求質因數分解,最後加起
來。原題的資料範圍是3*10^6,用好一點的實現的話完全是可以過的。但是,這道題資料範圍更大,經測試
這種演算法在我的電腦上需要2.5s以上才跑得出來,我們需要乙個更優秀的演算法。
篩法已經是線性的了,演算法的瓶頸在於分解質因數。
分析一下演算法一分解質因數的過程:對乙個數k分解質因數時,每次找到他的最小質因數s,然後
k div s,繼續分解。我們發現,每次k都變成乙個更小的合數,而這個合數本身在後面還要分解一次!!!
也就是說,對於k和2k,分解2k的時候把k也分解了一次,這是冗餘的!!!
由於k*(s*k)的質因數分解等於k^2的質因數分解加上s的質因數分解,因此我們可以構造乙個線性
演算法。開乙個陣列b,初值賦為1。令指標i從後往前掃,每次掃到乙個數k,若k是質數,跳過他。否則我們
求出n!的質因數分解了。
線性篩法(尤拉篩法)
嗯在剛剛 沒錯就是在幾分鐘之前 我學會了線性篩法 實在是乙個很好的篩法 正常的篩法,都會對乙個數篩多次 但是尤拉篩法不會 尤拉篩法是用它的最大因數去篩 別跟我說最小質因數,那個很難讓人理解 雖然最小質因數和最大因數是一樣的 我們假設乙個數k,它是t的最大因數 容易知道t是不唯一的 那我們要乘以乙個質...
素數篩法(素數篩 線性篩)
求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...
線性篩法(尤拉篩)
從前有乙個素數篩法叫埃拉託斯特尼篩法,它的思想很簡單,把1 n以內素數的整數倍的數字劃掉,留下的就全是素數,但是它的複雜度是o nlglgn 對於大量不友好資料會跪,於是線性曬登場了。include using namespace std int prime 1100000 primesize,ph...