Description
Input
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
Output
Sample Input
2 1000 53 87 123456789
Sample Output
7922 6060
先来了解一下何为‘扩展欧几里德定理’:扩展欧几里得算法是用已知a,b求解一组x,y,使他们满足贝祖等式:ax+by=gcd(a,b)=d
题解: (1)由题可知:读入的是n和B,且gcd(B,9973) = 1 ;
(2)假设(A/B)%9973 = k ; 所以 A/B = k + 9973*x ---> A = Bk + Bx*9973 ;
且n = A % 9973 ;替换可得 : n = (Bk +Bx*9973)%9973
(3)化简上式,因为是9973的倍数,所以取余为0 , 得: Bk % 9973 = n ;
(4)同(2)一样, 化简(3)式 , Bk = n + 9973* y ;两边同除n并且移相可得 ---> Bk/n-9973*y/n = 1 ;
(5)其符合 (k/n)*B - (y/n)*9973 = gcd(B,9973) = 1 ;
故求解所得 x , y 即为 x = (k/n) , y = -(y/n);(此处y因为前面定义问题冲突,并不是一个y);
AC代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std ;
void extend_gcd(ll a , ll b , ll &x , ll &y)
{
if(b==0)
{
x = 1 ;
y = 0 ;
return ;
}
extend_gcd(b,a%b,x,y);
int r = x;
x = y ;
y = r - (a/b)*y;
}
int main()
{
ll a , b , n , t ;
cin>>t;
while(t--)
{
ll x , y ;
cin>>n>>b;
extend_gcd(b,9973,x,y);
x = (x%9973+9973)%9973;//*此处的加是防止答案出现负数,加一层取余不影响结果;
cout<<(x*n)%9973<<endl;
}
return 0 ;
}