算法很美:同余方程组

同余方程组

在这里插入图片描述

解法

  • 逐级合并:
    x≡a1(modm1)
    x≡a2(modm2)
    x≡a3(modm3) 求x
    进行两两合并,得出两两合并后的通解,
    对于前两个方程组
    x=a1+k1m1
    x=a2+k2m2
    故消去x后得到 k1m1-k2m2=a2-a1 带入线性求解 可得到一个k1的特解
    即: x0=a1+k1m1
    则通解为 :x=x0+k[lcm(m1,m2)]; 即x≡x0[mod lcm(m1,m2)]
    更新此时的a=x0和m=lcm(m1,m2);并与下一组方程继续两两合并
    直到全部合并结束,最后x的值为 最后一个合并的x0%lcm(m1’,m2’)

代码

public static void main(String[] args) throws Exception {
		long[] a= {2,3,2};
		long[] m= {3,5,7};
		System.out.println(linerEquationGroup(a, m));
	}
	
	public static long linerEquationGroup(long[] a,long[] m) throws Exception {
			if(a.length==0&&a[0]==0)return m[0];
			
			for (int i = 1; i < a.length; i++) {
					long a2_a1=a[i]-a[i-1];
					long d = exGcd.linerEqutaion(m[i-1], -m[i], a2_a1);
					long lcm=m[i-1]*m[i]/d;
					long x0=a[i-1]+exGcd.x*m[i-1];
					a[i]=(x0%lcm+lcm)%lcm;
					m[i]=lcm;
				
			}
			return a[a.length-1]%m[m.length-1];
	}
	
	private static class exGcd {
		static long x;
		static long y;
		
		private static long  ex_gcd(long a,long b) {
			if(b==0) {
				x=1;
				y=0;
				return a;
			}
				
			long res=ex_gcd(b, a%b);
			long x1=x;
			x=y;
			y=x1-a/b*y;
			return res;
		}
		
		private static long linerEqutaion(long a,long b,long m) throws Exception {
			long d=ex_gcd(a, b);
			if(m%d!=0) {
				 throw  new Exception("无解");
			}else {
				long n=m/d;
				x*=n;
				y*=n;
				 return d;
			}
		}

	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值