解线性同余方程组

2019-04-14 19:17发布

前几天纠结了差不多一个多小时,终于把线性同余方程组的求解纠结清楚了……果然还是写下来怕自己忘记……其实qzone不适合写这种文章……不过反正也只有自己看就无所谓了……
嗯……归纳一下
线性同余方程
ax≡b(mod n)是一个同余方程,表示ax mod n=b(or (b mod n)),求解这样一个x
存在这样的x当且仅当gcd(a,n)|b
那么所有的解可以表示为{x0+kn/d} (d=gcd(a,n))
在n的完系中,共有d个解
那么怎样找到这样一个x0呢
若这个方程有解,d=gcd(a,n),根据裴蜀定理,存在整数对(y,z),使得ay+nz=d①,这个整数对可以由扩展欧几里得算法求得
我们发现ax mod n=b 可以表示为ax+ny‘=b②,他与①式非常相像
实际上,由于d|b,把①式乘一个b/d,即可得到ay*b/d+nz*b/d=b③
②式右边=③式右边,∴x=y*b/d
因为y已知,所以求得了这样一个x0,得到了整个方程的解


线性同余方程组
//设c=m2-m1,d=gcd(b1,b2)
先讨论两个线性同余方程的情况
x≡b1(mod m1)①
x≡b2(mod m2)②
①式等价于x=b1*y+m1,②式等价于x=b2*z+m2
将两式联立,整理可得b1y-b2z=c
这又是二元一次补丁方程ax+by=c的形式,根据裴蜀定理,有解的条件是d|(m2-m1)
所以可用ext_gcd解出y',z'
得到b1y'+b2z'=d③
③式乘一个c/d,得
b1y'*c/d+b2z'*c/d=m2-m1④
x=y'*c/d*b1+m1,得解

显然y'有可能是负数,回代会造成x的大小无法控制,如果要得到最小非负整数解怎么办呢

二元一次不定方程ax+by=c的通解为
x=x0+kb y=y0-ka (gcd(a,b)=1)⑤
而这里的a=b1*c/d,b=b2*c/d,c=m2-m1
所以我们可以把y’的范围控制在(0,b2/d)内
为什么是b2/d而不是b2*c/d呢,因为gcd(a,b)=c≠1,按照⑤式的出来的解是通解的真子集,所以在枚举时要除以一个d
所以我们可以把y'做这样的处理y'=(y' mod (b2/d)+(b2/d)) mod (b2/d)
这样得到的y'是最小的非负整数y',从而可解得最小的x

当线性同余方程组不止两个式,可采用上述解法先求得两个方程的解xs
然后构造出新的方程x≡xs(mod lcm(m1,m2))(若x有大于xs的解,那么他至少大于等于lcm(m1,m2))
然后与第三个式子联立,递推求解

若m1,m2,m3……mn两两互素,即lcm(mi,mj)=mi*mj,此时可使用中国剩余定理

以上讨论的是x不带系数的方程组求解
若x带系数,即构成aix≡bi(mod mi)这种形式
有两种做法

一是两边同除以gcd(ai,mi),变成ai'x≡bi'(mod mi') gcd(ai',mi')=1
此时可求ai'关于mi'的逆元e,最后化得x≡bi'*e(mod mi')的形式

还有一种是联立两式时把系数化成一样,没试过,不知道行不行……

终于写完了……边写边又开始纠结……