費馬小定理及其應用
阿新 • • 發佈:2018-08-16
素數 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 }
費馬小定理及其應用