引出一个(b/a)%m的计算,众所周知除法不能和取余混用。所以我们需要求a的逆元来转换成乘法。
先解释下什么是逆元(这里特指乘法逆元)。假设a、b、c是整数,m>1,且有ab=1(mod m)成立那么就说a和b互为模m的逆元。通俗的说,如果两个整数的乘积模m后等于1,就称他们互为md的逆元。
那么由定义知,求a模m的逆元,就是求解同余式ax=1(mod m),并且在实际使用中,一般把x的最小正整数解称为a模m的逆元。下面提到的逆元都是最小正整数解。显然同余式ax=1(mod m)是否有解取决于1%gcd(a,m)是否为0。
那么要求解同余式ax=c(mod m)的话,根据一系列的推论可以转化成求解ax+my=gcd(a,m)。
就得使用到扩展欧几里得算法:
代码:
int exGcd(int a, int b, int &x, int &y){
if(b==0) {
x = 1;
y = 0;
return a;
}
int g = exGcd(b, a%b, x, y);
int temp = x;
x = y;
y = temp-a/b*y;
return g;
}
那么可以得到使用扩展欧几里得求逆元的代码:
int inverse(int a, int b) {
int x, y;
int g = exGcd(a, m, x, y);
return (x%m+m)%m;
}
具体的推导百度吧,太多了。。。。。
还有一种使用费马小定理求逆元(要求m必须是素数且a不等于0(mod m)),一般就看m是不是素数就行。
代码:
int binpow(int a, int n) {
int res = 1;
while (n) {
if (n & 1) res = (res*a)%mod;
a = (a*a)%mod;
n>>=1;
}
return res;
}