尤拉篩 素數 基礎

2021-09-11 19:26:12 字數 1092 閱讀 7031

求乙個數是不是素數,我們最開始用到的方法是從2開始跑到這個數的前一項,如若這些數都不能被這個數整除,那麼就稱這個數是素數 。素數的概念是除了1和它本身之外不再有其他因數(除了1),我們稱這樣的數為素數。如果我們就按一般思路去實現求解這個數是不是素數,那麼會用for迴圈從2開始跑到這個數的前一項,每個數都進行這樣的操作,顯然時間複雜度太高了,肯定會超時。這時我們就用一種快速的方法來判斷乙個數是不是素數。

我們用的方法是尤拉篩求解素數,其原理是我們假設每乙個數都是素數,並都標記好初始值為零,用乙個一維陣列就行,這是我們就開始判斷了,如果這個數是素數,即標記好的這個數值為零,然後就從這個數開始向後迴圈,只要是這個數的倍數,那這些數就都不是素數,並標記為1,這樣下次迴圈就判斷出這個數就不是素數了。當然如果都從當前這個素數開始向後跑標記後面的元素為1,那這樣也跑了好多遍,我們的目的是用o(n)的複雜度計算出這個數是不是素數(當然先存在陣列裡複雜度就降到了o(1)),這時我們就得判斷了,如果這個數判斷過了就是非素數,那此時就不用再標記了,即當前這個數除以之前選出來的素數 若為零那就停止迴圈,進行下一次迴圈。

我們只需兩個素組就能解決,**如下

void olashai()

{ memset(isprime,0,sizeof(isprime));

for(ll i=2;i用這個方法需要兩個陣列,乙個用來標記,乙個用來存素數,這樣我們可以再輸入資料之前先把素數篩出來,後面用到就直接那這個陣列用就行了,這樣時間複雜度為o(1),當然如果題目還有什麼其他的要求,我們可以在這個函式裡面在新增上,例如給你乙個數求這個數之前有多少個素數,這樣我們可以再開乙個陣列用來記錄某一資料之前有多少個素數。

**見下

#include#include#include#includeusing namespace std;

const int maxn=1e6+5;

typedef long long ll;

ll prime[maxn],isprime[maxn];

ll tot=0;

ll dis[maxn];

void olashai()

{ memset(isprime,0,sizeof(isprime));

for(ll i=2;i繼續努力,天道酬勤!!!

線性篩素數(尤拉篩)

尤拉篩是o n 複雜度的篩素數演算法,1秒內埃篩能處理1e6的資料,而1e7的資料就必須用尤拉篩了。埃篩的基本思想是 素數的倍數一定是合數。尤拉篩基本思想是 任何數與素數的乘積一定是合數 演算法概述 遍歷 2,n 的所有數i,內層迴圈遍歷已經找到的素數prime j 將i prime j 標記為合數...

尤拉篩找素數

任何合數都可以表示為多個素數的乘積,合數肯定有乙個最小的質因子,通過這個最小質因子篩掉合數,保留素數。aizu0009 求小於或等於n的素數個數 n 1,999999 include include include include using namespace std const int maxa...

尤拉函式 素數篩

尤拉發現求小於等於n的正整數中有多少個數與n互質可以用這個公式 euler x x 1 1 p1 1 1 p2 1 1 p3 1 1 p4 1 1 pn 其中p1,p2 pn為x的所有素因數,x是不為0的整數。euler 1 1 唯一和1互質的數就是1本身 尤拉公式的延伸 乙個數的所有質因子之和是e...