题目连接:点击打开链接
解题思路:
由题知:n=A%9973,
有欧几里得可化为:A=9973*k1+n代入所求式子:
((9973*k1+n)/B)%9973)=x(记为x)
即为:(9973*k1+n)%9973=B*x,可化为:
9973*k1+n=9973*k2+B*x,可化为:
B*x-n=9973 *(k1-k2)=9973*y (B*x-n与9973成倍数关系)
可化为:B*x-9973*y=n
根据扩展欧几里得可知:gcd(B,9973)=1=n,因为x是B的乘法逆元,
接着乘法逆元讲,一般,我们能够找到无数组解满足条件,但是一般是让你求解出最小的那组解,怎么做?我们求解出来了一个特殊的解 x0 那么,我们用 x0 % 9973其实就得到了最小的解了。为什么?
可以这样思考:假设 a*x + m*y = 1
x 的通解不是 x0 + m/gcd*t 吗?(t为常数,这里的gcd为1)
那么,也就是说, a 关于m的逆元是一个关于m同余的,那么根据最小整数原理,一定存在一个最小的正整数,它是 a 关于m的逆元,而最小的肯定是在(0 , m)之间的,而且只有一个,这就好解释了。
但是,由于问题的特殊性,有时候我们得到的特解 x0 是一个负数,还有的时候我们的 m 也是一个负数这怎么办?
当 m 是负数的时候(该题化简出来的式子里-9973是负数),我们取 m 的绝对值就行了,当 x0 是负数的时候,他模上 m 的结果仍然是负数。
故x,y有一组唯一的解,所以x的解唯一。
代码如下:
#include<iostream>
using namespace std;
#define ll long long
int n;
ll b;
int t;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>b;
int i;
for(i=1; i<9973; i++)
{
if((b*i-n)%9973==0)
cout<<i<<endl;
}
}
return 0;
}
~step by step