首先要說明一些數學知識
乙個數可以分成兩個數的乘積,即c=ab。其中當a為c的最小質因子時,對於任意的c,顯然若a相同,則b必定各不相同;若a不相同則b可能相同或不相同。所以c=ab中,任意兩個的c分解出來的a和b至少有乙個不相同,即a不相同或者b不相同。
總結:只要a是c的最小質因子數,每次以a*b的形式去篩除c,且在a相同時b不相同,則就可以保證c只被篩除一次。
通過每一次迴圈將以su[j]作為最小質因數,篩除i*su[j]。當i%su[j]==0時,則i=su[j]某個數x,假設x可以分解出小於su[j]的質因子,那麼必然在之前的迴圈中滿足i%su[j]==0,跳出迴圈了。所以x的所有質因子必然大於su[j],因此保證了每次篩除中su[j]是isu[j]的最小質因子數。所以每個合數只被篩除一次。
// 尤拉篩法求素數
#include
#include
using namespace std;
#define n
1000010
int vi[n]
,su[n]
,cnt=
0,n;
void
print
(int n)
}int main()
}print
(n);
return0;
}
尤拉篩法求素數
尤拉篩法通過不篩除篩除過的數來將時間複雜度優化到 尤拉篩法求素數 首先,我們知道當乙個數為素數的時候,它的倍數肯定不是素數。所以我們可以從2開始通過乘積篩掉所有的合數。將所有合數標記,保證不被重複篩除,時間複雜度為o n 比較簡單 求小於等於n的素數的個數 include includeusing ...
尤拉篩法求素數
埃氏篩法確實大大提高了求素數的效率,但是會有很多合數被重複刪去,在資料大小超過1e8的時候會支撐不住。尤拉篩法便有效先看 解決了這個問題,將時間複雜度降低到了o n 先看 int ans 0,pri max n 尤拉篩法 bool vis max n void getpri vis i pri j ...
線性篩法求素數(埃氏篩法 尤拉篩法)
篩法都是初始化把所有數都先設為素數,然後篩除合數。理解起來比較簡單,就是從小到大的列舉每乙個數,標記它的所有倍數都是合數 非素數 放到u i 為false,u中的下標對應的就是這個數的值。bool u maxn int num,su maxn 1.埃氏篩法 void prime 從小到大的篩選素數,...