同余方程组
解法
- 逐级合并:
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;
}
}
}