素數(shù)專題

一.素數(shù)的一些性質(zhì):

  1. 素數(shù)的個數(shù)無限多(不存在最大的素數(shù))

  2. 存在任意長的一段連續(xù)數(shù),其中的所有數(shù)都是合數(shù)(相鄰素數(shù)之間的間隔任意大)

  3. 所有大于2的素數(shù)都可以唯一地表示成兩個平方數(shù)之差。

(證明:大于2的素數(shù)都是奇數(shù)。假設(shè)這個數(shù)是2n+1。由于 (n+1)2 = n2+2n+1,(n+1)2和n2就是我們要找的兩個平方數(shù)。下面證明這個方案是唯一的。如果素數(shù)p能表示成a2-b2,則p=a2-b2=(a+b)(a-b)。由于p是素數(shù),那么只可能a+b=p且a-b=1,這給出了a和b的唯一解。)

  1. 當n為大于2的整數(shù)時,2n+1和2n-1兩個數(shù)中,如果其中一個數(shù)是素數(shù),那么另一個數(shù)一定是合數(shù)。

  2. 如果p是素數(shù),a是小于p的正整數(shù),那么a(p-1) mod p = 1。(費馬小定理)

二.單個判斷素數(shù)

大于等于5的質(zhì)數(shù)一定和6的倍數(shù)相鄰

#include <iostream>
#include <math.h>
using namespace std;
int isPrime(int n)
{   //返回1表示判斷為質(zhì)數(shù),0為非質(zhì)數(shù),在此沒有進行輸入異常檢測
    float n_sqrt;
    if(n==2 || n==3) return 1;
    if(n%6!=1 && n%6!=5) return 0;
    n_sqrt=floor(sqrt((float)n));
    for(int i=5;i<=n_sqrt;i+=6)
    {
        if(n%(i)==0 | n%(i+2)==0) return 0;
    }
        return 1;
} 
int main()
{
    int flag;
    flag=isPrime(37);
    cout<<flag<<endl;
    return 0;
}

三.篩選素數(shù)

歐拉篩法

int prime[MAXN];
bool vis[MAXN];
int cnt=0;
void Euler_peime(int n)
{
    for(int i=2;i<=n;++i)
    {
        if(!vis[i])
        {prime[cnt++]=i;vis[i]=true;}//vis[i]置為true或不置true都可以
        for(int j=0;j<cnt;++j)
        {
            if(i*prime[j]>n)//判斷是否越界
                break;
            vis[i*prime[j]]=true;//篩數(shù)
            if(i%prime[j]==0)//時間復雜度為O(n)的關(guān)鍵!
                break;
        }
    }
}

用埃式篩法的同時,同一個數(shù)字也許會被篩選多次,比如6先被2篩選一次,再被3篩選一次,這樣就浪費了很多不必要的時間,而歐拉篩法通過if(i%prime[j]==0)break;這一步就避免了重復篩選的發(fā)生,我們舉個例子,比如,2先篩選了4,然后進行下一個循環(huán),3篩選6和9,當我們執(zhí)行到4的時候,可以發(fā)現(xiàn),當i==4時,第一次運行到if(i%prime[j]==0)這一步的時候就直接break;掉了,這也就是說,當我們的合數(shù)進入循環(huán)時,其實它已經(jīng)被之前的數(shù)篩選過了,所以當合數(shù)進入內(nèi)層循環(huán)時,內(nèi)層循環(huán)只執(zhí)行了一次,從而減少了時間復雜度。
比如:i=k x prime[j]; 我們?nèi)绻惶鲅h(huán)的話,繼續(xù)計算prime[j+1]---->i x prime[j+1]=k x prime[j] x prime[j+1];k x prime[j+1]會與i相等,于是式子就變成了i*prime[j],會被第二次篩到,所以加上這個判斷可以大大縮小復雜度。

if(i%prime[j]==0)//時間復雜度為O(n)的關(guān)鍵!
                break;

四.大素數(shù)判定(Miller-Rabin算法)

1.費馬小定理

a^p ≡ a (mod p)-->p為質(zhì)數(shù) 必要不充分
兩邊同除a得:
a^(p-1) ≡ 1 (mod p)

2.二次探測定理

如果(p為奇素數(shù))的話,則有x^2 ≡ 1 (mod p);
該方程有兩組解:
(1)x ≡ 1 (mod p)
(2)x ≡ p-1 (mod p)

3.算法步驟

(1)先使用費馬小定理 if(a^(n-1) ≡ 1 (mod n) ) 成立的話,就說明p為素數(shù);
(2)步驟1不成立的話,使用二次探測

while(n-1 為偶數(shù)){
  u = (n-1)/2;
  套用二次探測
  a^u ≡ 1 (mod n)?
  a^u ≡ n-1 (mod n)?
}

(3)換用a,繼續(xù)算法,一般當n<2^64時,a一般選用前7個素數(shù)(2, 3, 5, 7, 11, 13和17)進行測試,所有不超過341 550 071 728 320的數(shù)都是正確的。
一般我們直接獲取隨機數(shù)就可以。

4.代碼
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
#include<map>
#include<set>
#define MOD n
#define LL long long
#define UP 5
using namespace std;
int m;
LL  n;
LL qsc(LL a,LL b,LL mod){
  LL sum = 0;
  while(b){
    if(b&1)sum=(sum+a)%mod;
    a=(a+a)%mod;
    b>>=1;
  }return sum%mod;
}
LL pow(LL a,LL b,LL mod){
  LL res = 1;
  while(b){
    if(b&1)res=qsc(res,a,mod);
    a=qsc(a,a,mod);b>>=1;
  }return res%mod;
}
bool MR(){
  if(n==2)return true;
  if( (!(n&1)) || n<2 )return false;
  LL u=n-1,a,x,y;
  while(!(u&1))u>>=1;
  for(int i=0;i<1;++i){
    a=rand()%(n-2)+2;
    x=pow(a,u,n);int tmp=u;
    while(u<n){
      y=pow(x,2,n);
      if(y==1&&x!=1&&x!=n-1)return false;
      x=y;u*=2;
    }u=tmp;
    if(x!=1)return false;
  }return true;
}
int main(){
  srand(time(NULL));
  scanf("%d",&m);
  for(int i=1;i<=m;++i){
    scanf("%lld",&n);
    if(MR())printf("Yes\n");
    else printf("No\n");
  }return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,045評論 0 2
  • 三、RSA scalabilityRSA可擴展性 Obviously a post-quantum RSA pub...
    jorson2000閱讀 672評論 0 0
  • 數(shù)據(jù)結(jié)構(gòu)算法大全(用 PASCAL 描述) 1.數(shù)論算法 求兩數(shù)的最大公約數(shù) function gcd(a,b:i...
    心想事成_ae7e閱讀 581評論 0 0
  • 放學的時候,媽媽領(lǐng)我到宏偉超市去,給我買了水晶泥和亮粉,因為媽媽說攢到六朵小紅花就給我買兩樣我想要的東西,...
    王琳晶閱讀 417評論 0 0
  • 5月1假期之后剛上班,我收到原用友企業(yè)大學校長,也是我很好的朋友田俊國老師的微信,他說:“我做了一個艱難的決定,辭...
    繁花塢閱讀 1,723評論 13 23

友情鏈接更多精彩內(nèi)容