線性篩(篩素數)
阿新 • • 發佈:2021-10-21
從前有一個素數篩法叫埃拉託斯特尼篩法,它的思想很簡單,把1-n以內素數的整數倍的數字劃掉,留下的就全是素數,但是它的複雜度是O(NlglgN),對於大量不友好資料會跪,於是線性晒登場了。
#include <cstring> using namespace std; int prime[1100000],primesize,phi[11000000]; bool isprime[11000000]; void getlist(int listsize) { memset(isprime,1,sizeof(isprime)); isprime[1]=false; for(int i=2;i<=listsize;i++) { if(isprime[i])prime[++primesize]=i; for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++) { isprime[i*prime[j]]=false; if(i%prime[j]==0)break; } } }
以上就是線性晒程式碼,他與埃氏篩法大概有這麼幾點不同:
①:if(i%prime[j]==0)break;
這句程式碼保證了每個數最多被篩一次,將時間複雜度降到了線性。
證明如下:prime[]陣列中的素數是遞增的,當i能整除prime[j],那麼i*prime[j+1]這個合數肯定被prime[j]乘以某個數篩掉。
因為i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那麼i*prime[j+1]=(k*prime[j])*prime
[j+1]=k’*prime[j],接下去的素數同理。所以不用篩下去了。因此,在滿足i%prime[j]==0這個條件之前以及第一次
滿足改條件時,prime[j]必定是prime[j]*i的最小因子。