時間限制:10000ms
單點時限:1000ms
記憶體限制:256mb
描述小ho:小hi,上次我學會了如何檢測乙個數是否是質數。於是我又有了乙個新的問題,我如何去快速得求解[1,n]這個區間內素數的個數呢?
小hi:你自己有什麼想法麼?
小ho:有!我一開始的想法是,自然我們已經知道了如何快速判定乙個數是否是質數,那麼我就直接將[1,n]之間每乙個數判定一次,就可以得到結果。但我發現這個方法太笨了。
小hi:確實呢,雖然我們已經通過快速素數檢測將每一次判定的時間複雜度降低,但是n個數字的話,總的時間複雜度依舊很高。
小ho:是的,所以後來我改變了我的演算法。我發現如果乙個數p是質數的話,那麼它的倍數一定都是質數。所以我建立了乙個布林型別的陣列isprime,初始化都為true。我從2開始列舉,當我找到乙個isprime[p]仍然為true時,可以確定p一定是乙個質數。接著我再將n以內所有p的倍數全部設定為isprime[p*i]=false。
寫成偽**為:
isprime = true小hi:小ho你用的這個演算法叫做eratosthenes篩法,是一種非常古老的質數篩選演算法。其時間複雜度為o(n log log n)。但是這個演算法有乙個冗餘的地方:比如合數10,在列舉2的時候我們判定了一次,在列舉5的時候我們又判定了一次。因此使得其時間複雜度比o(n)要高。primecount = 0
for i = 2 .. n
if isprime[i] then
primecount = primecount + 1
multiple = 2
while (i * multiple ≤ n)
isprime[i * multiple] = false
multiple = multiple + 1
end while
end if
end for
小ho:那有沒有什麼辦法可以避免啊?
小hi:當然有了,乙個改進的方法叫做eular篩法,其時間複雜度是o(n)的。
輸入第1行:1個正整數n,表示數字的個數,2≤n≤1,000,000。
輸出第1行:1個整數,表示從1到n中質數的個數
素數篩模板不解釋。
**:
#define ll long long#include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=1000010
;int
su[maxn];
bool
shi[maxn];
int shai(int
n) }
returnp;}
intmain()
數論 HihoCoder1195 高斯消元
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小ho 喂不得了啦,那邊便利店的薯片半價了 小hi 啥?小ho 那邊的便利店在打折 啊。小hi 走走走,趕緊去看看 v 於是小hi和小ho來到了便利店。老闆為了 推出了組合包的形式,將不同數量的各類商品打包成乙個組合,顧客...
11 1 考試 數論 數論 二分
額,可以直接暴力,或二分,或者像我這麼sb 地分解質因數 因為p是質數,所以a b 1 二分即可 大佬們都用並查集,可是我不會啊 我只會線段樹的解法 複雜度 o nlog 2n 好像比並查集快一點點 哈哈 注意兩種不合法的情況 上面的兩個符合分別是交集,並集的意思 然後二分,直接模擬就好了 incl...
狀態壓縮 二 Hiho9 Hihocoder
歷經千辛萬苦,小hi和小ho終於到達了舉辦美食節的城市!雖然人山人海,但小hi和小ho仍然抑制不住興奮之情,他們放下行李便投入到了美食節的活動當中。美食節的各個攤位上各自有著非常多的有意思的小遊戲,其中乙個便是這樣子的 小hi和小ho領到了乙個大小為n m的長方形盤子,他們可以用這個盒子來裝一些大小...