Acwing---878. 线性同余方程 (Java)_数学知识_扩展欧几里得算法模板

原题链接

①. 题目

在这里插入图片描述

②. 思路

在这里插入图片描述

  • 先用扩展欧几里得算法求出一组整数 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;
	//扩展欧几里得模板  a * x + b * y = gcd(a, b) 
	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);
			//只要 b 是 gcd(a, m)的倍数即有解
			if(b%d==0) {
    
    
			    // x′=x0∗c/d
				long res=(long)x*b/d%m;
				System.out.println(res);
			}else {
    
    
				System.out.println("impossible");
			}
		}
	}

}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45480785/article/details/113896367