線性篩的思想是每個數隻會被篩一遍,因此時間複雜度是線性的(實際全域性vis是大於n的,但以每個數的遍歷次數來說恰好是1)
設乙個合數的**只有兩種:素數 × 素數,或者是 合數 × 最小的素數,這樣可以保證每個合數不會重複遍歷
如果i為素數,那就令prime[j]小於等於i來避免重複遍歷,所以i%prime[j]保證了prime[j]不大於i
如果i為合數,那假如i%prime[j]不為0,那prime[j]就是i×prime[j]分解的最小的素數,否則就意味著i裡面含有prime[j],而prime表是遞增的,後者的i×prime[j+1]所含素數的最小素數肯定不是prime[j+1](prime[j]最小),所以提前break掉
令人驚訝的是乙個i%prime[j]就完成了這麼繁雜的活
下面是測試用例
觀察一下資料,感受感受
15 = 5 × 3
12 = 6 × 2
18 = 9 × 2
45 = 15 × 3
#include#define rep(i,j,k) for(int i=j;i<=k;i++)
#define rrep(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
#define maxn 9999
#define maxsize 1010
const int maxn = 1e6+11;
#define dlen 4
const int mod = 100000007;
typedef long long ll;
bool isprime[maxn];
int prime[maxn],cnt,vis;
int sai(int n)
miu[i*prime[j]]=-miu[i]; //}}
}int main()
1 1
2 -1
3 -1
4 05 -1
6 17 -1
8 09 0
10 1
11 -1
12 0
13 -1
14 1
15 1
16 0
17 -1
18 0
19 -1
20 0
21 1
22 1
23 -1
24 0
25 0
26 1
27 0
28 0
29 -1
30 -1
31 -1
32 0
33 1
34 1
35 1
36 0
37 -1
38 1
39 1
40 0
41 -1
42 -1
43 -1
44 0
45 0
46 1
47 -1
48 0
49 0
50 0
總結 線性篩質數
怎麼篩素數 直接列舉i 2 n 1 i 2 rightarrow n 1 i 2 n 1,如果i ii是n nn的因數,則n nn一定是質數,如果找完都沒找到這樣的i ii說明n nn是合數,純粹是根據定義來判斷 bool check int n return true 考慮到如果乙個數i ii為n...
線性篩 區間篩
求l到r之間的素數1 l 231 1 1 leq l 1 l231 1由於範圍過大只需要求得r 2 sqrt 2 2r 線性篩素數時間複雜度o n int n,m int prime 100000 vis 100005 void primes int n for int j 1 j m j 區間篩素...
線性篩(尤拉篩)
昨天的考試跪的一塌糊塗 第一題水過,第二題帶wa的樸素,最後題忘了特判左端點全跪,分數比起預計得分整整打了個對折啊!步入正題 線性篩 尤拉篩 一般的篩法 ppt裡叫埃拉託斯特尼篩法,名字異常高貴 的效率是o nlglgn 其實很接近o n 啊!對於一些例如n 10000000的殘暴資料會跪,於是,線...