Problem Description
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
Output
对应每组数据输出(A/B)%9973。
Sample Input
2 1000 53 87 123456789
Sample Output
7922 6060
题解1
根据拓展欧几里德,Ax + By = g(A,B)必定有解
由题得A % 9973 = n,A = 9973y + n,A / B = x,所以Bx - 9973y = n
根据g(A,B) = 1,不必判断c是gcd(A,B)的倍数
利用扩展欧几里得模板计算Bx - 9973y = n的最小整数解即可
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<functional>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define CL(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
const int MOD = 1e9+7;
int n[20], m[20];
void ex_gcd(LL a, LL b, LL& d, LL& x, LL& y){
if(!b){
d = a;
x = 1;
y = 0;
}
else{
ex_gcd(b, a%b, d, y, x);
y -= x*(a/b);
}
}
int main(){
LL t, n, a, b, c, d, A, B, C, k, x, y;
int kcase = 1;
scanf("%lld", &t);
while(t--){
scanf("%lld%lld", &n, &B);
a = B;
b = 9973;
c = n;
ex_gcd(a, b, d, x, y);
c /= d;
x *= c;
b /= d;
x = (x%b+b)%b;
printf("%lld\n", x);
}
return 0;
}
题解2
设 A=B*N;
根据同余定理 : A % 9973 = (B % 9973 )*(N % 9973)% 9973
N % 9973为所求 又因为 N % 9973 属于【0,9972】 所以枚举N % 9973的值,设N % 9973 = i满足条件则输出
#include<stdio.h>
int main(){
int i,t,x;
scanf("%d",&t);
while(t--){
long long n, b;
scanf("%lld%lld", &n, &b);
for(i = 0; i < 9973; i++){
if((b * i - n) % 9973 == 0){
x = i;
break;
}
}
printf("%d\n",x);
}
return 0;
}