Miller Rabin質數測試

2022-03-15 18:58:10 字數 3512 閱讀 8274

本文主要討論使用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質數測試演算法。

如果p是奇素數,則x^2 ≡ 1(mod p)的解為x ≡ 1x ≡ p - 1(mod p)如果a^(n-1) ≡ 1 (mod n)成立,miller-rabin演算法不是立即找另乙個a進行測試,而是看n-1是不是偶數。如果n-1是偶數,另u=(n-1)/2,並檢查是否滿足二次探測定理即a^u ≡ 1a^u ≡ n - 1(mod n)

舉個matrix67 blog上的例子,假設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測試。

盡可能提取因子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;

}

//求取(x * y) % n

llong mod(llong x, llong y,llong n)

return res;

}

這個函式使用移位運算,通過將y轉換成二進位制形式,十分高效地求取了兩個數字乘積的餘數。

//求取(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;

}

即數字是否是素數的判定函式,依照我們在上文提出的加強定理,包含如下要點:

github:

個人部落格:

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...