一元线性同余方程
定义
在数论中,线性同余方程是最基本的同余方程,“线性”表示方程的未知数次数是一次,即形如:
ax≡b(mod n) 的方程。
解法(并不会证明)
对于线性同余方程
ax≡b(mod m)
,设
d=(a,m)
若
d∤b
则方程无解,否则方程恰有
d
个模
当有解时,设
a=d∗a0
,
m=d∗m0
方程两边同时除以
d
并去模,得
而此时因为
(a0,m0)
=1,因此我们可以考虑使用扩展欧几里得算法进行求解。
设解为
x0
,则因为其他解关于
m0
同余
(a0x≡b/d (mod m0))
,所以所有的解为
x0,x0+m0,x0+2m0......
代码:
int r=exgcd(a,m,x,y);//扩欧
if (b%r)
return -1;
x=x*(b/r)%m;
for (int i=1;i<=r;i++)
ans[i]=(x+(i-1)*m/r)%m;
一元线性同余方程组
任何一元同余方程都可变成若干个形如 x≡b(mod m) 的方程
ax≡b(mod m) —> x≡ba−1(mod m)
而一元线性同余方程组可以两两进行合并,成为一个一元线性同余方程进行求解。
解法
对于两个方程
x≡b1(mod m1)
x≡b2(mod m2)
当
(m1,m2)∣(b1−b2)
时有解
此时两个方程分别可以看成:
x+m1y1=b1
x+m2y2=b2
因为 x 相同,所以我们可以把两式相减,得
因为
(m1,m2)∣(b1−b2)
,因此我们仍然可以用扩展欧几里得算法进行求解。
解得
y1
和
y2
后,我们就可以进行合并
b(x)=m1∗y1+b1
m=m1∗m2/(m1,m2)
于是我们就得到了新的方程。然后不断合并接下来的方程即可。
最终解即为
x≡b(mod m)
,即
x=b
代码:
for (LL i=1;i<n;i++){
LL aa,mm,x,y;
scanf("%lld%lld",&aa,&mm);
LL r=exgcd(a,x,aa,y);//扩欧,a和m之前先读下来
if ((mm-m)%r!=0) f=true;
LL t=aa/r;
x=(x*((mm-m)/r)%t+t)%t;
m+=a*x;
a*=(aa/r);
}