數學:費馬小定理

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

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

聽說它是歐拉定理的一種特殊狀況,也就是blog

比較神奇,聽說很出名很出名很出名string

先回顧一下乘法逆元io

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

若是這個m是個質數,那麼費馬小定理就派上用場嘍gc

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

推導過程:db

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

例題是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 }
相關文章
相關標籤/搜索