原题链接
①. 题目
②. 思路
- 先用扩展欧几里得算法求出一组整数 x’,y’, 使得
a∗x'+m∗y'=gcd(a,m)
。 然后 x=x'∗b/gcd(a,m)%m
即是所求解。
- a * x ≡ b (mod m) 变形为拓展欧几里得形式:a * x + b * y = gcd(a, b)
- 原式变为: a * x = m * y + b (注:mod m 为 b, 则相当于结果为 m 的倍数和 b 的和)
- a * x - m * y = b
- 另y1 = -y得:a * x + m * y1 = b
- 根据拓展欧几里得定理,
只要 b 是 gcd(a, m)的倍数即有解!
- 另d = gcd(a, m), 我们得到的式子其实是:a * x + m * y1 = gcd(a, m) = d (注;上面的b其实就是d的倍数)
- 所以左右同乘 b / d 即可转化为:
a * x * b / d + m * y1 * b / d = b * b / d = b
- 即最后答案为:
res = x * d / b % m
③. 学习点
转换成扩展欧几里得公式,进行模板套用
④. 代码实现
import java.util.Scanner;
public class Main {
static int x,y;
static int exgcd(int a,int b) {
if(b==0) {
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b);
int tmp=x;
x=y;
y=tmp-a/b*y;
return d;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n-->0) {
int a=sc.nextInt();
int b=sc.nextInt();
int m=sc.nextInt();
int d=exgcd(a, m);
if(b%d==0) {
long res=(long)x*b/d%m;
System.out.println(res);
}else {
System.out.println("impossible");
}
}
}
}