1. 程式人生 > >費馬小定理及其應用

費馬小定理及其應用

素數 mage 質數 style names .com col () 神奇

假如p是質數,且gcd(a,p)=1,那麽 a^(p-1)≡1(mod p)

也就是a^(p-1) %p=1

據說它是歐拉定理的一種特殊情況,也就是

技術分享圖片

比較神奇,據說很出名很出名很出名

先回顧一下乘法逆元

技術分享圖片

x的最小整數解稱為a模m的逆元

如果這個m是個質數,那麽費馬小定理就派上用場嘍

這個時候x的最小整數解是

技術分享圖片

推導過程:

技術分享圖片

只可意會不可言傳的樣子。

例題是HDU4704,題意是:求1-n中,組成n的不同種數

用隔板法思考,在n個1裏面插隔板有幾種插法

結果是2^(n-1)

然後呢?就是計算它了,質數的範圍是1e6,那麽好,按題意取模

也就是求2^(n-1)%mod

費馬小定理a^b%c=a^(b%(c-1))%c

使用的前提是mod是個質數

對於任意自然數,當要求a^p%m時,就可以利用費馬小定理化簡,只需求(a^(p%(m-1)))%m(p是素數)

記住這句話,題目就很顯然了

我們將n拆成多個 a*(p-1) + k ,也就是2^n = 2^[a*(p-1) + k ] % mod = 2^k % mod

在這裏p直接等於mod,就那麽中括號的左半部分因為費馬小定理就化沒了,只剩下個k

要求的是2^(n-1),計算出k後,減一直接快速冪即可

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
4 const long long MOD=1000000007; 5 char s[1000005]; 6 long long cal(long long m) 7 { 8 int len=strlen(s); 9 long long ans=0; 10 for(int i=0;i<len;i++) 11 ans=(ans*10+s[i]-0)%m; 12 return ans; 13 } 14 long long pow_mod(long long a,long long b) 15 { 16 long long ans=1; 17 while
(b!=0) 18 { 19 if(b&1) ans=ans*a%MOD; 20 a=a*a%MOD; 21 b>>=1; 22 } 23 return ans; 24 } 25 int main() 26 { 27 while(scanf("%s",s)==1) 28 { 29 long long k=cal(MOD-1); 30 printf("%lld\n",pow_mod(2,k-1)); 31 } 32 return 0; 33 }

費馬小定理及其應用