[數論系列] 素數篇

本章介紹關於素數的一些數論,限於篇幅不給出證實,須要證實的朋友自行相關證實。優化

什麼是素數?只能被本身和1整除的數就是素數。spa

利用這個性質咱們很容易獲得下面的素數判斷方法。code

bool isPrime(int x){
    if(x==1)return 0;
    for(int i=2;i*i<=x;i++)
        if(x%i==0)return 0;
    return 1;
}

這裏解釋一下爲何是i*i<=x,i*i<x轉化一下就是i<=sqrt(x)。blog

想想,若是咱們枚舉到sqrt(x)都沒有找到能夠被它整除的數,後面也就不可能有能夠被它整除的數了,由於一個>sqrt(x)的數要是被x整除了,它的商確定是<sqrt(x)的,而咱們已經枚舉過<=sqrt(x)的數了,裏面沒有,因此>sqrt(x)的約數也是不可能有的。ci

這種判斷方法的時間複雜度是O(sqrt(n))的,空間複雜度是O(1)的。it

再給出一個判斷方法,這個方法的時間複雜度大概是O(sqrt(n)/3)的,空間複雜度也是O(1)。io

bool isPrime(int x){
    if(x==1)return false;
    if(x==2||x==3)return true;
    if(x%6!=1&&x%6!=5)return false;
    for(int i=5;i*i<=x;i+=6)
        if(x%i==0||x%(i+2)==0)return false;
    return true;
}

證實被我吃了。class

而後就是幾種素數的篩法了。咱們規定下文中討論的[]爲向下取整。效率

首先是著名的埃篩,Eratosthenes篩法。百度

埃篩基於這樣一個想法:對於一個數x,它的倍數2x,3x,4x,5x...都不是質數。

因而,咱們從2開始從小到大掃描每一個數x,把它的倍數2x,3x,4x,...,[N/x]*x標記爲合數

當掃描到一個數時,若它未被標記爲合數,則它就不能被2~x-1中的任何數整除,它就是質數。

可是咱們會發現,埃篩會重複標記一個數。好比8,它會被2標記,還會被4標記,這樣影響了效率。

因而咱們考慮優化,對於每一個數,從x^2開始把x^2,(x+1)*x,...,[N/x]*x標記爲合數。

給出代碼:

int comp[maxn],prime[maxn];
//合數標記(composite),素數標記
void Eratothenes(int n){//篩到哪裏
   for(int i=2;i<=n;i++){ if(comp[i])continue; prime[i]=1;//i是質數 for(int j=i;j<=n/i;j++)comp[i*j]=1; } }

優化後的埃篩的時間複雜度是O(nloglogn),接近線性,並且很好寫,推薦熟記。

那有沒有線性篩呢,有,可是我的認爲,會埃篩就夠了,不必爲了卡常寫到線性。

想了解的能夠自行百度。

接下來給出一些定理,仍是同樣,不證。

1. 惟一分解定理

若整數x>=2,則x必定能夠以惟一的形式表示成若干個素數的乘積。

能夠寫做:x=p1^c1*p2^c2*p3^c3*...*pm^cm。

其中,ci均爲正整數且pi均爲素數,知足p1<p2<...<pm

2. 威爾遜定理

沒啥用的定理,若p爲素數,則(p-1)! ≡ 1(mod p)。

3. 威爾遜定理的逆定理

若對於某一正整數p,有(p-1)! ≡ -1(mod p),則p爲素數。

3. 費馬定理

若p爲素數,x爲正整數,且x和p互質,則x^(p-1) ≡ 1(mod p)。

4. 費馬小定理

若p爲素數,則x^p ≡ x(mod p)。

 

還有一些東西:( ﹁ ﹁ ) ~→待填坑  

相關文章
相關標籤/搜索