費馬小定理 素性判斷 蒙哥馬利演算法
轉載於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,那麼
公倍數:兩個不同的自然數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*(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次乘法。
- /*計算n^p*/
- unsigned power(unsigned n,unsigned p)
- {
- for(int i=0;i<p;i++) n*=n;
- return n;
- }
該死的乘法,是時候優化一下了!把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
優化後的演算法如下:
- unsigned Power(unsigned n,unsigned p)
- {
- unsigned main=n; //用main儲存結果
- unsigned odd=1; //odd用來計算“剩下的”乘積
- while (p>1)
- {//一直計算,直到指數小於或等於1
- if((p%2)!=0)
- {// 如果指數p是奇數,則說明計算後會剩一個多餘的數,那麼在這裡把它
- 乘到結果中
- odd*=main; //把“剩下的”乘起來
- }
- main*=main; //主體乘方
- p/=2; //指數除以2
- }
- return main*odd; //最後把主體和“剩下的”乘起來作為結果
- }
夠完美了嗎?不,還不夠!看出來了嗎?main是沒有必要的,並且我們可以有更快的程式碼來判斷奇數。要知道除法或取模運算的效率很低,所以我們可以利用偶數的一個性質來優化程式碼,那就是偶數的二進位制表示法中的最低位一定為0!
完美版:
- unsigned Power(unsigned n, unsigned p)
- { // 計算n的p次方
- unsigned odd = 1; //oddk用來計算“剩下的”乘積
- while (p > 1)
- { // 一直計算到指數小於或等於1
- if (( p & 1 )!=0)
- { // 判斷p是否奇數,偶數的最低位必為0
- odd *= n; // 若odd為奇數,則把“剩下的”乘起來
- }
- n *= n; // 主體乘方
- p /= 2; // 指數除以2
- }
- return n * odd; // 最後把主體和“剩下的”乘起來作為結果
- }
========================================================
5."蒙格馬利”快速冪模演算法
後面我們會用到這樣一種運算:(X^Y)%Z。但問題是當X和Y很大時,只有32位的整型變數如何能夠有效的計算出結果?
考慮上面那份最終的優化程式碼和再上面提到過的積模分解公式,我想你也許會猛拍一下腦門,吸口氣說:“哦,我懂了!”。
下面的講解是給尚沒有做出這樣動作的同學們準備的:
X^Y可以看作Y個X相乘,即然有積模分解公式,那麼我們就可以把Y個X相乘再取模的過程分解開來,比如:(17^25)%29則可分解為:( ( 17 * 17 ) % 29 * ( 17 * 17 ) % 29 * ……
如果用上面的程式碼將這個過程優化,那麼我們就得到了著名的“蒙格馬利”快速冪模演算法:
- unsigned Montgomery(unsigned n, unsigned p, unsigned m)
- { // 快速計算 (n ^ e) % m 的值,與power演算法極類似
- unsigned r = n % m; // 這裡的r可不能省
- unsigned k = 1;
- while (p > 1)
- {
- if ((p & 1)!=0)
- {
- k = (k * r) % m; // 直接取模
- }
- r = (r * r) % m; // 同上
- p /= 2;
- }
- return (r * k) % m; // 還是同上
- }
上面的程式碼還可以優化。下面是蒙格馬利極速版:
- unsigned Montgomery(unsigned n,unsigned p,unsigned m)
- { //快速計算(n^p)%m的值
- unsignedk=1;
- n%=m;
- while(p!=1)
- {
- if(0!=(p&1))k=(k*n)%m;
- n=(n*n)%m;
- p>>=1;
- }
- return(n*k)%m;
- }
=====================================================
6.怎麼判斷一個數是否為素數?
1)笨蛋的作法:
- bool IsPrime(unsigned n)
- {
- if (n<2)
- {
- //小於2的數即不是合數也不是素數
- throw 0;
- }
- for (unsigned i=2;i<n;++i)
- {
- //和比它小的所有的數相除,如果都除不盡,證明素數
- if (n%i==0)
- {
- //除盡了,則是合數
- returnfalse;
- }
- }
- returntrue;
- }
2)下面是小學生的做法:
- bool IsPrime(unsigned n)
- {
- if (n<2)
- {
- //小於2的數即不是合數也不是素數
- throw 0;
- }
- for(unsigned i=2;i<n/2+1;++i)
- {
- // 和比它的一半小數相除,如果都除不盡,證明素數
- if ( 0 == n % i )
- {
- // 除盡了,合數
- returnfalse;
-
相關推薦
費馬小定理 素性判斷 蒙哥馬利演算法
轉載於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