1. 程式人生 > >費馬小定理 素性判斷 蒙哥馬利演算法

費馬小定理 素性判斷 蒙哥馬利演算法

轉載於http://blog.csdn.net/arvonzhang/article/details/8564836

1.約定

x%y為x取模y,即x除以y所得的餘數,當x<y時,x%y=x,所有取模的運算對象都為整數。
x^y表示x的y次方。乘方運算的優先順序高於乘除和取模,加減的優先順序最低。
見到x^y/z這樣,就先算乘方,再算除法。
A/B,稱為A除以B,也稱為B除A。
若A%B=0,即稱為A可以被B整除,也稱B可以整除A。
A*B表示A乘以B或稱A乘B,B乘A,B乘以A……都一樣。

複習一下小學數學
公因數:兩個不同的自然數A和B,若有自然數C可以整除A也可以整除B,那麼

C就是A和B的公因數。

公倍數:兩個不同的自然數A和B,若有自然數C可以被A整除也可以被B整除,那麼C就是A和B的公倍數。

互質數:兩個不同的自然數,它們只有一個公因數1,則稱它們互質。

費馬是法國數學家,又譯“費爾馬”,此人巨牛,他的簡介請看下面。不看不知道,一看嚇一跳。

2.費馬小定理:

有N為任意正整數,P為素數,且N不能被P整除(顯然N和P互質),則有:N^P%P=N(即:N的P次方除以P的餘數是N)。

但是我查了很多資料見到的公式都是這個樣子:

(N^(P-1))%P=1後來分析了一下,兩個式子其實是一樣的,可以互相變形得到。

原式可化為:

(N^P-N)%P=0(即:N的P次方減N可以被P整除,因為由費馬小定理知道N的P次方除以P的餘數是N)把N提出來一個,N^P就成了你N*(N^(P-1)),那麼(N^P-N)%P=0可化為:

(N*(N^(P-1)-1))%P=0
請注意上式,含義是:N*(N^(P-1)-1)可以被P整除

又因為N*(N^(P-1)-1)必能整除N(這不費話麼!)
所以,N*(N^(P-1)-1)是N和P的公倍數,小學知識了^_^

又因為前提是N與P互質,而互質數的最小公倍數為它們的乘積,所以一定存在

正整數M使得等式成立:N*(N^(P-1)-1)=M*N*P
兩邊約去N,化簡之:N^(P-1)-1=M*P
因為M是整數,顯然:N^(P-1)-1)%P=0即:N^(P-1)%P=1
============================================

3.積模分解公式

先有一個引理,如果有:X%Z=0,即X能被Z整除,則有:(X+Y)%Z=Y%Z
設有X、Y和Z三個正整數,則必有:(X*Y)%Z=((X%Z)*(Y%Z))%Z

想了很長時間才證出來,要分情況討論才行:

1.當X和Y都比Z大時,必有整數A和B使下面的等式成立:
X=Z*I+A(1)
Y=Z*J+B(2)
不用多說了吧,這是除模運算的性質!
將(1)和(2)代入(X*Y)modZ得:((Z*I+A)(Z*J+B))%Z乘開,再把前三項的Z提一個出來,變形為:(Z*(Z*I*J+I*A+I*B)+A*B)%Z(3

因為Z*(Z*I*J+I*A+I*B)是Z的整數倍……暈,又來了。
概據引理,(3)式可化簡為:(A*B)%Z又因為:A=X%Z,B=Y%Z,代入上面的式子,就成了原式了。

2.當X比Z大而Y比Z小時,一樣的轉化:
X=Z*I+A
代入(X*Y)%Z得:
(Z*I*Y+A*Y)%Z
根據引理,轉化得:(A*Y)%Z
因為A=X%Z,又因為Y=Y%Z,代入上式,即得到原式。
同理,當X比Z小而Y比Z大時,原式也成立。

3.當X比Z小,且Y也比Z小時,X=X%Z,Y=Y%Z,所以原式成立。
=============================================
========

4.快速計算乘方的演算法

如計算2^13,則傳統做法需要進行12次乘法。

  1. /*計算n^p*/
  2. unsigned power(unsigned n,unsigned p)  
  3. {  
  4.     for(int i=0;i<p;i++) n*=n;  
  5.     return n;  
  6. }  

該死的乘法,是時候優化一下了!把2*2的結果儲存起來看看,是不是成了:

4*4*4*4*4*4*2
再把4*4的結果儲存起來:16*16*16*2 
一共5次運算,分別是2*2、4*4和16*16*16*2

這樣分析,我們演算法因該是隻需要計算一半都不到的乘法了。
為了講清這個演算法,再舉一個例子2^7:2*2*2*2*2*2*2 
兩兩分開:(2*2)*(2*2)*(2*2)*2 
如果用2*2來計算,那麼指數就可以除以2了,不過剩了一個,稍後再單獨乘上
它。

再次兩兩分開,指數除以2: ((2*2)*(2*2))*(2*2)*2
實際上最後一個括號裡的2 * 2是這回又剩下的,那麼,稍後再單獨乘上它 現在指數已經為1了,可以計算最終結果了:16*4*2=128

優化後的演算法如下:

  1. unsigned Power(unsigned n,unsigned p)   
  2. {  
  3.    unsigned main=n; //用main儲存結果
  4.    unsigned odd=1; //odd用來計算“剩下的”乘積
  5.    while (p>1)   
  6.    {//一直計算,直到指數小於或等於1
  7.         if((p%2)!=0)  
  8.         {// 如果指數p是奇數,則說明計算後會剩一個多餘的數,那麼在這裡把它
  9. 乘到結果中  
  10.             odd*=main; //把“剩下的”乘起來
  11.         }  
  12.         main*=main; //主體乘方
  13.         p/=2; //指數除以2
  14.    }  
  15.    return main*odd; //最後把主體和“剩下的”乘起來作為結果
  16. }  

夠完美了嗎?不,還不夠!看出來了嗎?main是沒有必要的,並且我們可以有更快的程式碼來判斷奇數。要知道除法或取模運算的效率很低,所以我們可以利用偶數的一個性質來優化程式碼,那就是偶數的二進位制表示法中的最低位一定為0!

完美版:

  1. unsigned Power(unsigned n, unsigned p)   
  2. // 計算n的p次方
  3.     unsigned odd = 1; //oddk用來計算“剩下的”乘積
  4.     while (p > 1)  
  5.     { // 一直計算到指數小於或等於1
  6.        if (( p & 1 )!=0)  
  7.       { // 判斷p是否奇數,偶數的最低位必為0
  8.              odd *= n; // 若odd為奇數,則把“剩下的”乘起來
  9.       }  
  10.       n *= n; // 主體乘方
  11.       p /= 2; // 指數除以2
  12.      }  
  13.     return n * odd; // 最後把主體和“剩下的”乘起來作為結果
  14. }  

========================================================

5."蒙格馬利”快速冪模演算法

後面我們會用到這樣一種運算:(X^Y)%Z。但問題是當X和Y很大時,只有32位的整型變數如何能夠有效的計算出結果?

考慮上面那份最終的優化程式碼和再上面提到過的積模分解公式,我想你也許會猛拍一下腦門,吸口氣說:“哦,我懂了!”。

下面的講解是給尚沒有做出這樣動作的同學們準備的:

X^Y可以看作Y個X相乘,即然有積模分解公式,那麼我們就可以把Y個X相乘再取模的過程分解開來,比如:(17^25)%29則可分解為:( ( 17 * 17 ) % 29 * ( 17 * 17 ) % 29 * ……

如果用上面的程式碼將這個過程優化,那麼我們就得到了著名的“蒙格馬利”快速冪模演算法:

  1. unsigned Montgomery(unsigned n, unsigned p, unsigned m)  
  2. // 快速計算 (n ^ e) % m 的值,與power演算法極類似
  3.     unsigned r = n % m; // 這裡的r可不能省
  4.     unsigned k = 1;  
  5.     while (p > 1)  
  6.     {  
  7.         if ((p & 1)!=0)  
  8.         {  
  9.             k = (k * r) % m; // 直接取模
  10.         }  
  11.         r = (r * r) % m; // 同上
  12.         p /= 2;  
  13.     }  
  14.     return (r * k) % m; // 還是同上
  15. }  

上面的程式碼還可以優化。下面是蒙格馬利極速版:
  1. unsigned Montgomery(unsigned n,unsigned p,unsigned m)  
  2. //快速計算(n^p)%m的值
  3.       unsignedk=1;  
  4.       n%=m;  
  5.      while(p!=1)  
  6.      {  
  7.          if(0!=(p&1))k=(k*n)%m;  
  8.          n=(n*n)%m;  
  9.          p>>=1;  
  10.     }  
  11.     return(n*k)%m;  
  12. }  

=====================================================

6.怎麼判斷一個數是否為素數?

1)笨蛋的作法:

  1. bool IsPrime(unsigned n)  
  2. {  
  3.     if (n<2)  
  4.     {     
  5.         //小於2的數即不是合數也不是素數
  6.         throw 0;  
  7.     }  
  8.     for (unsigned i=2;i<n;++i)  
  9.     {   
  10.         //和比它小的所有的數相除,如果都除不盡,證明素數
  11.         if (n%i==0)  
  12.         {  
  13.             //除盡了,則是合數
  14.             returnfalse;  
  15.         }  
  16.     }  
  17.     returntrue;  
  18. }  
一個數去除以比它的一半還要大的數,一定除不盡,所以還用判斷嗎??

2)下面是小學生的做法:

  1. bool IsPrime(unsigned n)  
  2. {  
  3.     if (n<2)  
  4.     {  
  5.         //小於2的數即不是合數也不是素數
  6.         throw 0;  
  7.     }  
  8.     for(unsigned i=2;i<n/2+1;++i)  
  9.     {   
  10.         // 和比它的一半小數相除,如果都除不盡,證明素數
  11.         if ( 0 == n % i )  
  12.         {   
  13.             // 除盡了,合數
  14.             returnfalse;  
  15. 相關推薦

    定理 素性判斷 演算法

    轉載於http://blog.csdn.net/arvonzhang/article/details/8564836 1.約定 x%y為x取模y,即x除以y所得的餘數,當x<y時,x%y=x,所有取模的運算對象都為整數。 x^y表示x的y次方。

    定理判斷素數

    // 根據費馬小定理判斷P是否為一個素數 #include <iostream> #include<stdio.h> #include<algorithm> using namespace std; typedef long

    篩素數方法(二)—— 定理及MR素數判斷

    註明:本文中的x^y表示x的y次方 一、費馬小定理 1.1 內容 若p為素數,a為正整數,且gcd(a,p)=1,則a^(p−1)≡1(mod p)。1.2 證明 因為p為素數,所以gcd(

    hdu4549矩陣快速冪+定理

    次方 pla pragma nod 技術分享 gif 矩陣 end eof 轉移矩陣很容易求就是|0 1|,第一項是|0| |1 1| |1| 然後直接矩陣快速冪,要用到費馬小定理 :假如p

    HDU 4704 Sum(隔板原理+組合數求和公式+定理+快速冪)

    ace php 模板 erl char printf 證明 style ron 題目傳送:http://acm.hdu.edu.cn/showproblem.php?pid=4704 Problem Description Sample Input 2 Sam

    SDOI 2010--古代豬文(Lucas算法&定理&中國剩余定理)

    費馬小定理 答案 nbsp ont using main long long 資料 合數 發現幾乎每次數論題洛谷總是讓我TLE一個點。。。。 附圖: 最後那個點優化了很久終於過了。。。。 題意

    【數學基礎】【歐拉定理模板】【定理

    基礎 int 復雜度 amp pan -1 log 分治 質數 費馬小定理:當p是一個質數時,且a和p互質,有ap-1=1(mod p) (歐拉定理的一種特殊情況) 歐拉定理:如果a和n互質,那麽aφ(n)=1(mod n) 對於任意a,b,n就有 ab=

    SPOJ DCEPC11B - Boring Factorials 定理

    pri med www. while mat const res 取余 multi 題目鏈接:http://www.spoj.com/problems/DCEPC11B/ 題目大意:求N!對P取余的結果。P是素數,並且abs(N-P)<=1000。 解題思路:wiki

    51Nod 1119 機器人走方格 V2 組合數學 定理

    素數 實現 逆元 整數 要求 合數 init sin 排列組合 51Nod 1119 機器人走方格 V2 傳送門 高中的排列組合應該有講過類似的題,求路徑條數就是C(m+n-2,n-1) 想法很簡單,問題是怎麽實現……這裏要用到費馬小定理,用到逆元 費馬小定理:假如p是素數

    HDU 5201 The Monkey King(組合數學)(隔板法+容斥定理+定理)

    逆元 cst 大於 ont amp space pro http strong http://acm.hdu.edu.cn/showproblem.php?pid=5201題意:給你n個桃子要你分給m只猴子,猴子可以得0個桃子,問有多少種方法,但是有一個限制條件: 第一只猴

    【bzoj5118】Fib數列2 定理+矩陣乘法

    n-2 fin 描述 print std fine ont str CP 題目描述 Fib定義為Fib(0)=0,Fib(1)=1,對於n≥2,Fib(n)=Fib(n-1)+Fib(n-2) 現給出N,求Fib(2^n). 輸入 本題有多組數據。第一行一個整

    定理

    out urn long clas cout spa nbsp pre gpo 計算分數n/m對c取模 long long int c; long long int quick(long long int n,long long int m) { lon

    hdu 3037 定理+逆元求組合數+Lucas定理

    void log 打表 數學 mod turn ret iostream toc 組合數學推推推最後,推得要求C(n+m,m)%p 其中n,m小於10^9,p小於1^5 用Lucas定理求(Lucas定理求nm較大時的組合數) 因為p數據較小可以直接階乘打表求逆元

    定理的證明

    利用 就是 個數 .... code 先來 bsp 存在 相同 數論: 1.費馬小定理: mod:a mod p就是a除以p的余數 費馬小定理:a^(p-1)≡1(mod p) 前提:p為質數,且a,p互質 互質:a和p相同的因數為1.

    牛客挑戰賽B隨機數 (定理+對大數的取模+組合數學出現次數為奇數的問題)

    IT pre 運行 tps long 時間 DC 之間 typedef 鏈接:https://www.nowcoder.com/acm/contest/129/B來源:牛客網 時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言5242

    定理與歐拉定理

    img 由於 假設 因數 歐拉 參考 表示 height 計算 歐拉定理和費馬小定理有許多重要的應用,常見的我們可以用它來化簡計算 費馬小定理是歐拉定理的特例 一、費馬小定理            證明: 由(a,m) = 1,知m不是a的素因數;又因為m不是1、2、3..

    定理及其應用

    素數 mage 質數 style names .com col () 神奇 假如p是質數,且gcd(a,p)=1,那麽 a^(p-1)≡1(mod p) 也就是a^(p-1) %p=1 據說它是歐拉定理的一種特殊情況,也就是 比較神奇,據說很出名很出名很出名 先回顧一下乘

    歐拉定理 / 定理證明

    重新 nbsp data- data aid span hellip class ram 主要部分轉自百度百科:https://baike.baidu.com/item/歐拉定理 內容: 在數論中,歐拉定理,(也稱費馬-歐拉定理)是一個關於同余的性質。歐拉定理表明,若n

    HDU - 1576(定理求逆元)

    math src typedef pow ble inpu show font type 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Othe

    2018 CCPC網絡賽 Dream (定理

    turn adc per -- bottom from ever img making Dream Problem Description Freshmen frequently make an error in computing the power of a sum o