费马小定理:
若存在整数a,p,满足gcd(a,p)==1(即a,p互质),则有a^(p-1)≡1(mod p)。
(就是a的p-1次幂对p取模与1恒等于)
证明:
两条引理帮助证明:
引理1:
设a,b,c为三个任意整数,p为任意正整数,满足gcd(c,p)==1。则可以根a*c=b*c(mod p)推出a≡b(mod p)。
推理过程:
a*c=b*c(mod p)
=>a*c-b*c=0(mod p)
=>(a-b)*c=0(mod p)
=>a=b(mod p)【由于c和p互质,就相当于是(a-b)是p的整数倍,所以c可以约】
引理2:
设p为一个整数且p>1,b也是一个整数且gcd(p,b)==1。
如果序列a[0],a[1],a[2]...a[n]是模p的一个完全剩余系,
则b*a[0],b*a[1],b*a[2]...b*a[n]也是模p的一个完全剩余系。
推理过程:
反证法:如果后者序列不是模p的一个完全剩余系,则存在b*a[i]与b*a[j]同余,即为b*a[i]=b*a[j](mod p)(i!=j)
根据引理1且gcd(b,q)==1可以知道:a[i]=a[j](mod p)。当然这是不可能的。
所以b*a[0],b*a[1],b*a[2]...b*a[n]是模p的一个完全剩余系。
拓展:完整剩余系
费马小定理证明:
构造一个素数p的完全剩余系{1,2,3,...,p-1}。
可知道N={n,2*n,3*n,...(p-1)*n}也是完全剩余系。
则根据完全剩余系相乘的性质可以知道:
1*2*3*...*(p-1)=n*2*n*3*n*...*(p-1)*n mod p
=>(p-1)!=n^(p-1)*(p-1)! mod p
=>1=n^(p-1) mod p
=>n^(p-1)=1(mod p)
分数取模(乘法逆元)
要求分数取模,首先要知道乘法逆元,简单来说,乘法逆元的定义:
对于整数a,p且gcd(a,p)==1,则一定存在唯一一个b满足a*b≡1(mod p)。
逆元是对分数取模用的:
对于除法取模不成立,即(a/b)%p≠(a%p/b%p)%p。
求逆元的思路:(一般ACM的题目都是对1e9+7这种素数取模,所以gcd(a,p)==1)
a*b=1(mod p) => b=1/a(mod p)。
根据费马小定理:b^(p-1)=1(mod p) => b^(p-2)=1/b(mod p)
可以看出来逆元1/b (mod p)=b^(p-2)
可以得出a/b对质数p取模就是 a*b^(p-2) mod p 。
例题:
HDU-6574
这里给出运用快速幂求乘法逆元的写法:
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
ll ksm(ll a ,ll k)
{
ll rec=1;
while(k)
{
if (k&1)
rec=((rec%mod)*(a%mod))%mod;
a=((a%mod)*(a%mod))%mod;
k>>=1;
}
return rec%mod;
}
int main()
{
ll n;
while(cin>>n)
{
cout<<((n+1)*ksm(2*n,mod-2)%mod)%mod<<endl;
}
return 0;
}
也可以算是一个模板。