模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
(a^b) % p = ((a % p)^b) % p
推论:
若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);
若a≡b (% p),c≡d (% p),则 (a + c) ≡ (b + d) (%p),(a - c) ≡ (b - d) (%p),
(a * c) ≡ (b * d) (%p),(a / c) ≡ (b / d) (%p);
对于(a÷b)%p,如果存在b1,这个b1满足的条件是,b * b1%p=1。。这样,将式子(a÷b)%p乘上b * b1%p,结果不变,式子变为(a * b1)%p。这样就将除法转换为乘法计算。这样的b1称作b模p的逆元。
怎样求逆元呢?
1.费马小定理
如果p为素数,且gcd(b,p)=1,那么就有bp-1 = 1 (modP),即b * bp-2 =1(modP),则bp-2 即为b模P的逆元。
代码实现:
2.扩展欧几里得求逆元
#include <bits/stdc++.h>
using namespace std;
void ExPower( int b, int p, int & a, int & k ) {
if( p == 0 ) {
a = 1; k = 0;
return;
}
ExPower( p, b % p, k, a );
k -= b / p * a;
return;
}
int main() {
int b, p;
cin >> b >> p;
int a, k;
ExPower( b, p, a, k );
if( a < 0 ) a += p;
cout << a << endl;
return 0;
}