博主剛寫了一篇Luogu T1125的解題報告,里面涉及到歐拉篩法。本篇博文會介紹一些素數篩法和素數驗證法。
博主的數論并不是特別好,各路大神輕點噴
素數篩法
1. Eratosthenes篩法
又名:埃拉托斯特尼篩法
時間復雜度:$O(nlog_{2}{log_{2}n})$
難度:☆
具體代碼:
memset(check,false,sizeof(check));
int tot=0;
for(int i=2;i<=n;i++)
if(!check[i])
{
prime[++tot]=i;
for(int j=i*2;j<=n;j+=i)//i的倍數都不是素數
check[j]=true;
};
2. Euler篩法
又名:歐拉篩法、線性篩法
時間復雜度:$O(n)$
難度:★
具體代碼:
for(int i=2;i<=m;i++)
{
if(!check[i])prime[++tot]=i;
for(int j=1;j<=tot;j++)
{
if(i*prime[j]>m)break;//超了范圍就不做了,減少運行時間
check[i*prime[j]]=true;//一個數乘另一個數所得到的數一定不是素數
if(i%prime[j]==0)break;//此時i是一個合數,退出
};
};
驗證素數
普通驗證素數法
時間復雜度:$O(\sqrt n)$
難度:☆
bool flag=true;
for(int i=1;i<=trunc(sqrt(prime));i++)
if(prime%i==0)flag=false;//置不是素數標志
Miller-Rabin
時間復雜度:$O(k*log_{2}n)$ k是次數(見下文)
難度:★★★
這里只說明一下原理,關于代碼,自行百度吧。
- 根據費馬小定理,隨機選一個數$a\in(1,p)$,若$a^{p-1}\equiv1$(mod p)則很有可能是素數。多次嘗試(嘗試k次)若都成立若都成立則判定為素數。
- 但是合數也有可能能通過這一測試:Carmichael數
- Carmichael概念:
卡邁克爾數是一種合數,使得對于所有跟n互質的整數a:$a^{n-1}\equiv1$(mod n) - 這種數用此方法測試時,除非random出其因子,不然都無法判斷為合數。例如:6。
- 二次探測定理:若n為素數,方程$x^2\equiv1$(mod n)小于n的正整數解只有$x=1$和$x=n-1$。
- 先計算出m、j,使得$n-1=m*2^j$且j盡可能大。
- 隨機選一個數$a\in(1,n)$
- 計算x=$a^m$mod n
- 然后將x不斷平方j次,重復如下步驟:
1. 計算y=$x^2$mod n
2. 如果y=1并且$x\neq1,n-1$,此時一定不是素數,退出測試
3. x=y;
4. 如果y=1,暫時認為是素數,回到2.繼續下一輪
若上述計算中沒有滿足2.和4.而正常退出,即不滿足$a^{n-1}\equiv1$(mod n),一定不是質數
Ps.此方法參考了陳淙靚在清北學堂的課件
原文請查看我的博文
此博文到此結束,感謝惠讀