日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【学习笔记】Miller-Rabin(米勒-拉宾)素性测试,附常用表

發布時間:2023/12/3 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【学习笔记】Miller-Rabin(米勒-拉宾)素性测试,附常用表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

@TOC

素性測試是檢驗一個給定的整數是否為素數的測試。

最簡單的就是用 n\sqrt{n}n? 以內的數去試除。這是確定性的算法,即能準確知道 nnn 是否為質數。

但今天學習的是一種隨機算法。

Fermat 小定理

如果 ppp 是一個質數,且 a%p≠0a\%p≠0a%p?=0,則有 ap?1≡1(modp)a^{p-1}\equiv 1\pmod pap?11(modp)

利用 Fermat定理 可以得到一個測試合數的有力算法:對 n>1n>1n>1,選擇 a>1a>1a>1, 計算 an?1modna^{n-1} \mod nan?1modn

  • 若結果 ≠1\neq 1?=1,則 nnn 是合數。

  • 若結果 =1=1=1, 則 nnn 可能是素數,并被稱為一個以 aaa 為基的弱可能素數 (a-PRP) 。

    nnn 是合數,則又被稱為一個以 aaa 為基的偽素數。

這個算法的成功率是相當高的。在 <25000000000<25000000000<25000000000109198740510919874051091987405 個素數中,一共只有 218532185321853 個以 222 為基的偽素數。

但不幸的是,存在無窮多個被稱為 Carmichael數(卡邁克爾數)的整數,對于任意與其互素的整數 aaa 算法的計算結果都是 111

最小的五個 Carmichael數 是 561、1105、1729、2465、2801561、1105、1729、2465、28015611105172924652801

miller_rabin(米勒-拉賓)素性測試

定理 :如果 ppp 是個 >2>2>2 的質數,則方程 x2≡1(modp)x^2\equiv 1\pmod px21(modp) 的解只有 x=±1x=±1x=±1

證明:

x2≡1(modp)?x2?1≡0(modp)?(x+1)(x?1)≡0(modp)x^2\equiv 1\pmod p\Rightarrow x^2-1\equiv 0\pmod p\Rightarrow (x+1)(x-1)\equiv 0\pmod px21(modp)?x2?10(modp)?(x+1)(x?1)0(modp)

p∣(x+1)∧p∣(x?1)p|(x+1)\wedge p|(x-1)p(x+1)p(x?1)。則一定存在兩個數 j,kj,kj,k,使得 x+1=jp,x?1=kpx+1=jp,x-1=kpx+1=jp,x?1=kp,兩式相減 2=(k?j)p2=(k-j)p2=(k?j)p,不可能。

所以只可能是 p∣(x+1)∨p∣(x?1)p|(x+1)\vee p|(x-1)p(x+1)p(x?1)

p∣(x+1)p|(x+1)p(x+1),則 x+1=kp?x≡?1(modp)x+1=kp\Rightarrow x\equiv -1\pmod px+1=kp?x?1(modp)

p∣(x?1)p|(x-1)p(x?1),則 x?1=kp?x≡1(modp)x-1=kp\Rightarrow x\equiv 1\pmod px?1=kp?x1(modp)

以上定理的逆否命題:當方程 x2≡1(modp)x^2\equiv 1\pmod px21(modp) 有一個解 x≠?1∧x≠1x\neq-1\wedge x\neq 1x?=?1x?=1,則 ppp 一定不是質數。

miller_rabin 是一個質數判斷算法,采用隨機算法能夠在很短的時間里判斷一個數是否是質數.

如何將卡邁克爾數甄別出來,這里要用到 二次探測方法。

算法流程:

  • ppp 是要判斷的數,222 特判后,ppp 如果是質數必須是奇數

  • p?1p-1p?1 分解為 2r?k2^r*k2r?k,則有 ap?1=(ak)2ra^{p-1}=(a^k)^{2^r}ap?1=(ak)2r

  • 可以先求出 aka^kak,然后將其不斷平方,并取模 ppp

  • 對于任意的 0<a<p0<a<p0<a<p,有 ak≡1(modp)a^k\equiv 1\pmod pak1(modp),或者 a2s?k≡?1(modp),0≤s<ra^{2^s*k}\equiv-1\pmod p,0\le s<ra2s?k?1(modp),0s<r

    只要有一個等式成立,那么后面不斷平方結果也是 111,在代碼實現時就會立即跳出。

    如果一個都沒有成立則說明一定不是個質數。

但是當 ppp 為合數的時候,也可能會騙過檢測,這就是“偽素數”。

如果挑選多個不同的 aaa 來檢測,那么就會降低騙過的概率。

這也就是 miller_rabin 要多次操作的原因。

容錯率是 14c\frac{1}{4}^c41?c,取決于操作次數 ccc

在競賽中,用固定的幾個數就夠了,附表。

n≤n≤naaa
20472
13736532,3
908019131,73
253260012,3,5
47591231412,7,61
11220046696332,3,13,1662803
21523028987472,5,7,11
34747496603832,5,7,11,13
3415500717283212,3,5,7,11,13,17
38251230565464130512,3,5,7,11,13,17,19

HDU2138

#include <cstdio> using namespace std; #define int long long int test[5] = { 2, 3, 61 };int qkpow( int x, int y, int mod ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans; }bool dfs( int n, int a, int d ) {if( n == a ) return 1;if( ! ( n & 1 ) ) return 0;while( ! ( d & 1 ) ) d >>= 1;int x = qkpow( a, d, n );while( d ^ ( n - 1 ) and x ^ 1 and x ^ ( n - 1 ) ) {x = x * x % n;d <<= 1;}return x == n - 1 or ( d & 1 ); }bool isprime( int n ) {if( n == 2 ) return 1;for( int i = 0;i < 2;i ++ ) if( ! dfs( n, test[i], n - 1 ) ) return 0;return 1; }signed main() {int T, n;while( ~ scanf( "%lld", &T ) ) {int sum = 0;for( int i = 1;i <= T;i ++ ) {scanf( "%lld", &n );if( isprime( n ) ) sum ++;}printf( "%lld\n", sum );}return 0; }

總結

以上是生活随笔為你收集整理的【学习笔记】Miller-Rabin(米勒-拉宾)素性测试,附常用表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。