解線性同余方程組


想必學完exgcd的各位dalao們都已經明白如何求解同余方程了

今天本蒟蒻只是想講講線性同余方程組的解法供各位大佬批評指錯

我們現在有一些線性同余方程

X=b1 (mod a1)

X=b2 (mod a2)

...

X=bn (mod an)

對於前面第一個方程,我們可以用exgcd求出一個X滿足一式

不妨設X=a1*y1+b1

若存在X滿足二式,則a1*y1+b1=b2 (mod a2)

所以y1=(b2-b1)/a1 (mod a2)

該式有解當且僅當(b2-b1)|gcd(a1,a2)

所以a1y1+a2y2=b2-b1

那么我們就可以用exgcd求出y1的解,進而求出X

那么問題來了,一式二式合並后是什么呢?

我們可以證明在lcm(a1,a2)中有且僅有一個X滿足條件,利用一些初中同余知識就可以,在這里就不詳細證明了

由此我們得到一個新方程X=X(mod lcm(a1,a2))

用這個方程再和后面的方程合並,for example,anslcm(a1,a2)+a3y3=b3-X

這樣一個一個往下求便可以求出答案

下面是一個裸的模板

#include<cstdio>	
#define ll long long 			
ll x,m,M,r,y,z;
ll gcd(ll a,ll b) {return a%b==0 ? b:gcd(b,a%b);} 
void inv(ll a,ll b) {
	if (a%b==0) 
	{z=0; y=1; return;}
	inv(b,a%b);
	ll r=z;
	z=y,y=r-a/b*y;
}
int main()
{
	int n;
	scanf("%d",&n);
	x=0; m=1;
	for (int i=1;i<=n;i++){
		scanf("%lld%lld",&M,&r);
		ll b=r-x,d=gcd(m,M);
		if (b%d!=0) {
			printf("-1");
			return 0;
		}
		inv(m/d,M/d);
		ll t=b/d*z%(M/d);
		x=x+m*t;
		m*=M/d;
	}
	printf("%lld\n\n",x>0 ? x:x+m);
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM