本文主要討論使用miller-rabin演算法編寫素數的判定演算法,題目**於hihocoder。
時間限制:10000ms
單點時限:1000ms
記憶體限制:256mb
描述
使用miller-rabin演算法進行質數素數測試,要求輸入乙個數字,對其是否是素數進行判定,並列印出相對應的結果。
輸入
第1行:1個正整數t,表示數字的個數,10≤t≤50
第2..t+1行:每行1個正整數,第i+1
行表示正整數a[i]
,2≤a[i]≤10^18
輸出
第1..t行:每行1個字串,若a[i]為質數,第i行輸出"yes",否則輸出"no"
樣例輸入
3 37
9
樣例輸出
yes
yesno
miller-rabin演算法是一種基於費馬小定理的擴充套件演算法,首先我們需要知道什麼是費馬小定理,然後還要知道整個miller-rabin演算法是如何擴充套件出來的。
費馬小定理:對於質數也即是說:假設我們要測試p
和任意整數a
,有a^p ≡ a(mod p)(同餘)
。反之,若滿足a^p ≡ a(mod p)
,p
也有很大概率為質數。將兩邊同時約去乙個
a
,則有a^(p-1) ≡ 1(mod p)
n
是否為質數。我們可以隨機選取乙個數a
,然後計算a^(n-1) mod n
,如果結果不為1
,我們可以100%斷定n
不是質數。
否則我們再隨機選取乙個新的數a進行測試。如此反覆多次,如果每次結果都是1,我們就假定n是質數。
該測試被稱為fermat測試。需要注意的是:fermat測試不一定是準確的,有可能出現把合數誤判為質數的情況。
miller和rabin在fermat測試上,建立了miller-rabin質數測試演算法。
如果舉個matrix67 blog上的例子,假設p
是奇素數,則x^2 ≡ 1(mod p)
的解為x ≡ 1
或x ≡ p - 1(mod p)
如果a^(n-1) ≡ 1 (mod n)
成立,miller-rabin演算法不是立即找另乙個a
進行測試,而是看n-1
是不是偶數。如果n-1
是偶數,另u=(n-1)/2
,並檢查是否滿足二次探測定理即a^u ≡ 1
或a^u ≡ n - 1(mod n)
。
n=341
,我們選取的a=2
。則第一次測試時,2^340 mod 341=1
。由於340
是偶數,因此我們檢查2^170
,得到2^170 mod 341=1
,滿足二次探測定理。同時由於170
還是偶數,因此我們進一步檢查2^85 mod 341=32
。此時不滿足二次探測定理,因此可以判定341
不為質數。
將這兩條定理合起來,也就是最常見的miller-rabin測試。
盡可能提取因子github:2
,把n-1
表示成d*2^r
,如果n
是乙個素數,那麼或者a^d mod n==1
,或者存在某個i
使得a^(d*2^i) mod n=n-1 (0<=i這裡需要注意的是,我們將該定理作為判定條件,仍然是乙個不確定的概率判定條件。miller-rabin素性測試同樣是不確定演算法,我們把可以通過以a
為底的miller-rabin測試的合數稱作以a為底的強偽素數(strong pseudoprime)。第乙個以2為底的強偽素數為2047。第乙個以2和3為底的強偽素數則大到1 373 653。所以我們在實際使用過程中,使用
rand()
函式生成隨機數,或者進行多次檢測判定,還是能夠得到比較高的判定成功率,miller-rabin演算法對於素數的研究判定有著巨大的輔助作用。#include #include using namespace std;
typedef long long llong;
//求取(x * y) % n
llong mod(llong x, llong y,llong n)
return res;
}//求取(x ^ y) % n
llong get_mod(llong x, llong y, llong n)
return res;
}//編寫bool函式,判定是否為素數
bool is_prime(llong n, int t)
//根據二次探測定理,只要不滿足(a == 1) || (a == n - 1),就會一直遍歷下去,直到最後返回false
if(i >= k)
return false;}}
return true;
}//主函式
int main()
return 0;
}
這個函式使用移位運算,通過將y轉換成二進位制形式,十分高效地求取了兩個數字乘積的餘數。//求取(x * y) % n
llong mod(llong x, llong y,llong n)
return res;
}
//求取(x ^ y) % n
llong get_mod(llong x, llong y, llong n)
return res;
}
即數字是否是素數的判定函式,依照我們在上文提出的加強定理,包含如下要點://編寫bool函式,判定是否為素數
bool is_prime(llong n, int t)
//根據二次探測定理,只要不滿足(a == 1) || (a == n - 1),就會一直遍歷下去,直到最後返回false
if(i >= k)
return false;}}
return true;
}
個人部落格:
Miller Rabin質數測試
費馬小定理 對於質數p和任意整數a,有a p a mod p 同餘 反之,若滿足a p a mod p p也有很大概率為質數。將兩邊同時約去乙個a,則有a p 1 1 mod p 也即是說 假設我們要測試n是否為質數。我們可以隨機選取乙個數a,然後計算a n 1 mod n,如果結果不為1,我們可以...
Miller Rabin質數測試
1.費馬小定理 費馬小定理 對於質數p和任意整數a,a p 1 mod 1不滿足的一定是合數,滿足的大概率是素數。2.miller rabin質數測試 如果滿足費馬小定理,則進一步驗證如果p是奇素數,則 x 2 1 mod p 的解為 x 1 或 x p 1 mod p 乙個例子 舉個matrix6...
Miller Rabin質數測試
這種質數演算法是基於費馬小定理的乙個擴充套件。費馬小定理 對於質數p和任意整數a,有a p a mod p 同餘 反之,若滿足a p a mod p p也有很大概率為質數。將兩邊同時約去乙個a,則有a p 1 1 mod p 也即是說 假設我們要測試n是否為質數。我們可以隨機選取乙個數a,然後計算a...