题意很清楚,给出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的情况下使用,题目正好符合这个情况.
#includeusing 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; }