一元线性同余方程
定义
在数论中,线性同余方程是最基本的同余方程,“线性”表示方程的未知数次数是一次,即形如:
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);
}