x ≡ r 1 ( m o d a 1 ) x\equiv r_1(mod\ a_1) x≡r1(mod a1)
x ≡ r 2 ( m o d a 2 ) x\equiv r_2(mod\ a_2) x≡r2(mod a2)
… \dots …
x ≡ r k ( m o d a k ) x\equiv r_k(mod\ a_k) x≡rk(mod ak)
方法一: x ≡ r 1 ( m o d a 1 ) ⟶ x = r 1 + a 1 y 1 x\equiv r_1(mod\ a_1) \longrightarrow x=r_1+a_1y_1 x≡r1(mod a1)⟶x=r1+a1y1 x ≡ r 2 ( m o d a 2 ) ⟶ x = r 2 + a 2 y 2 x\equiv r_2(mod\ a_2) \longrightarrow x=r_2+a_2y_2 x≡r2(mod a2)⟶x=r2+a2y2 联立: a 1 y 1 − a 2 y 2 = r 2 − r 1 a_1y_1-a_2y_2=r_2-r_1 a1y1−a2y2=r2−r1 求得: y 1 y_1 y1的一个解 y ′ y' y′, y 1 = y ′ + k a 2 g c d ( a 1 , a 2 ) y_1=y'+k\frac {a_2}{gcd(a_1,a_2)} y1=y′+kgcd(a1,a2)a2 带入原式: x = r 1 + a 1 ( y ′ + k a 2 g c d ( a 1 , a 2 ) ) x=r_1+a_1(y'+k\frac {a_2}{gcd(a_1,a_2)}) x=r1+a1(y′+kgcd(a1,a2)a2) 化简: x = r 1 + a 1 y ′ + k a 1 a 2 g c d ( a 1 , a 2 ) x=r_1+a_1y'+k \frac {a_1a_2}{gcd(a_1,a_2)} x=r1+a1y′+kgcd(a1,a2)a1a2
再化简得到: x ≡ r 1 + a 1 y ′ ( m o d a 1 a 2 g c d ( a 1 , a 2 ) ) x\equiv r_1+a_1y'(mod\ \frac {a_1a_2}{gcd(a_1,a_2)}) x≡r1+a1y′(mod gcd(a1,a2)a1a2) 这样就可以继续与后面的式子联立了
ll solve(ll *a,ll *r,ll n) { ll a1=a[1],r1=r[1]; for(int i=2;i<=n;++i) { ll a2=a[i],r2=r[i]; ll A=a1,B=a2,M=r2-r1,X,Y; ll GCD=exgcd(A,B,X,Y); if(M%GCD!=0) return -1; ll b1=a2/GCD; X=(X*M/GCD%b1+b1)%b1; r1=r1+a1*X; a1=a1*a2/GCD; } return r1; }方法二:中国剩余定理 假设已经求出了前k-1个方程的解,现在联立第k个求解 L C M = ∏ i = 1 k − 1 a i LCM=\prod_{i=1}^{k-1} a_i LCM=∏i=1k−1ai,前面的解为 x k − 1 x_{k-1} xk−1。我们需要求出 t t t,满足下面的式子 x k − 1 + t × L C M ≡ r k ( m o d a k ) x_{k-1}+t\times LCM\equiv r_k(mod\ a_k) xk−1+t×LCM≡rk(mod ak) 求出 t t t 之后,得到一个新的解 x k = x k − 1 + t × L C M x_k=x_{k-1}+t\times LCM xk=xk−1+t×LCM 把LCM更新后,再取模
ll excrt(ll *a,ll *r,ll n) { ll LCM=a[1],ans=r[1]; for(int i=2;i<=n;i++) { ll A=LCM,B=a[i],M=(r[i]-ans%B+B)%B,X,Y; ll GCD=exgcd(A,B,X,Y); if(M%GCD!=0) return -1; ll b1=B/GCD; X=(X*(M/GCD)%b1+b1)%b1; ans+=X*LCM; LCM*=b1; ans=(ans%LCM+LCM)%LCM; } return ans; }