解線性同余方程組
阿新 • • 發佈:2018-02-02
得到 cst 條件 合並 markdown long cti 線性同余方程組 code
想必學完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; }
解線性同余方程組