在測試一些非常大的數時,如果用根號n的方法判斷也會耗掉大量時間,實際上我們有更快的方法——miller-rabin隨機法
我們知道,費馬小定理:假如p是質數,且**(a,p)=1**,那麼a^(p-1)≡1(mod p)。即假如p是質數,且a,p互質,那麼a的(p-1)次方除以p的餘數恆等於1。
在大多數情況下費馬小定理的逆定理都是成立的,那麼我們就得到了乙個定理的直接應用,對於待驗證的數p,我們不斷取a∈[1,p-1]且a∈z,驗證a^(p-1) mod p是否等於1,不是則p果斷不是素數,共取s次。其中a^(p-1) mod p可以通過把p-1寫成二進位制,由(a*b)mod c=(a mod c)*b mod c,可以在t=log(p-1)的時間內計算出解,如考慮整數相乘的複雜度,則一次計算的總複雜度為log³(p-1)。這個方法叫快速冪取模。
我們還有這樣乙個定理:對於0x=1或p-1
我們令p-1=(2^t )*u,即p-1為u二進位制表示後面跟t個0。我們先計算出x[0]=a^u mod p ,再平方t次並在每一次模p,每一次的結果記為x[i],最後也可以計算出a^(p-1) mod p。若發現x[i]=1而x[i-1]不等於1也不等於p-1,則發現p必然不是素數。
通過這個兩個定理的應用,出錯率大大降低,可以說基本不出錯。
#include
using
namespace std;
typedef
long
long ll;
ll n;
inline ll mul
(ll a,ll b,ll p)
//快速乘
return ans;
}inline ll poww
(ll x,ll num,ll p)
//快速冪
return sum;
}inline
bool
miller_rabin
(long
long n)
//miller_rabin演算法,隨機法判斷大質數
if(x!=1)
return
false
;//費馬小定理
}return
true;}
intmain()
MillerRabin素數測試法
知道大家比較關心正確,網上教程好難找到資料,我就自己去wiki翻了 if n 2,047,it is enough to test a 2 if n 1,373,653,it is enough to test a 2 and 3 if n 9,080,191,it is enough to tes...
篩法判素數(大數)
哈哈,這次,大家又要聽我胡說一番嘍,對於計算機大家通常認為它的記憶力可以是無限度的,其實不然,它的記憶力也是有限的,它在主函式中最大記憶也不過幾千個,因此,當童鞋們,想要定義上萬個數的時候,千萬銘記要把陣列定義到外面喲,不然計算機可是會發脾氣,直接爆棧,讓你欲哭無淚的喲。在篩法這道題中因為數字較大最...
隨機素數法
在介紹素數測試相關演算法之前,先要引入尤拉定理和費馬定理。尤拉定理 對於任意的整數n 1,a n 1 mod n 對所有的a z n都成立。其中 n 為z n的規模。n n 1 1 p 可以理解成初始有一張的表,然後對每個能整除n的p,在表中刪除p的倍數後剩下的數。z n定義為中與n互質的元素。例如...