数学:费马小定理

假如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 }
相关文章
相关标签/搜索