题意很清楚,给出n = A % 9973, B gcd(B, 9973)为1, 求(A/B)%9973.
模运算有很多性质:(a+b) % c==(a % c + b % c) %c , (a-b) % c==(a % c - b % c) % c, (a*b) % c==(a % c * b % c) % c,遗憾的是除法没有这个性质.
不过可以通过求B的乘法逆元来求得.
解法:(a / b) % c == a * b^(-1) % c 其中b^(-1)为b的乘法逆元,乘法逆元可以通过拓展欧几里得算法求得.
推导:(a / b) ≡ x (mod c) ==>两边乘上一个b得到a ≡ bx (mod c) ==>两边乘上b mod n的乘法逆元得到 ==>a * b^(-1) ≡ b * b^(-1) * x (mod c) ==> a * b^(-1) ≡ x (mod c)
这种方法只能在gcd(b,c)为1的情况下使用,题目正好符合这个情况.
#include <cstdio>
using namespace std;
int ext_gcd(int a, int b, int & x, int & y){
if(!b){
x = 1, y = 0;
return a;
}
int gcd = ext_gcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return gcd;
}
int inv(int a, int n){
int x, y, gcd;
gcd = ext_gcd(a, n, x, y);
return gcd == 1 ? (x + n) % n : -1;
}
int main(int argc, char const *argv[]){
int T;
scanf("%d", &T);
while(T--){
int n, B;
scanf("%d %d", &n, &B);
int inverse = inv(B, 9973);
printf("%d\n", (n * inverse) % 9973);
}
return 0;
}