Han Xin Soldiers of
Question: given n-group divisor m[i] and remainder r[i], this n group (M[i],r[i]) solves an X, making x mod m[i] = r[i]
Solution:
It is difficult to solve the solution of multiple equations directly from the beginning, so we start with n = 2 recursion
Known:
X mod m[1] = r[1]x mod m[2] = r[2]
So there are two numbers, k[1], k[2]
x = k[1]*m[1] + r[1= k[2]*m[2] + r[2]
Because the values are the same, therefore:
k[1]*m[1] + r[1] = k[2]*m[2] + r[2]= k[1 ]*m[1]-k[2]*m[2] = r[2]-r[1]
A = m[1], B = m[2], c = r[2]-r[1], x = k[1], y = k[2] Then the upper style becomes Ax + by = C
is the extension of Euclid, can see my previous blog http://www.cnblogs.com/ygdblogs/p/5476395.html
Since each two equations can be combined into one, continuous operation, transformed into an equation, can solve the solution of multiple equations
Pseudo code:
M = m[1], R = r[1]for i=2 .. N D=gcd (M, m[i]) C= R[i]-R If (c mod d) Then//the case of no solutionReturn-1End If (K1, K2)= EXTEND_GCD (m/d, m[i]/d)//extended Euclidean calculation k1,k2K1 = (C/D * k1) mod (M[i]/d)//Extended Solution SystemR = r + K1 * M//calculation x = m[1] * k[1] + r[1]M = m/d * M[i]//Solution LCM (M, m[i])R%= M//solves the merged new R, while keeping R minimumEnd for If (R<0) then R= R +MEnd Ifreturn R
Source:
#include <stdio.h>#include<iostream>typedefLong Longll;ll m[1010], r[1010], X, Y;ll gcd (ll a,ll b) {if(A%b = =0)returnb; returnGCD (b, a%b);}voidEXTEND_GCD (ll a,ll b) {if(b==0) {x=1; Y=0; } Else{EXTEND_GCD (b,a%b); ll T=x; X=y; Y=t-(A/b) *x; }}intMain () {intN; ll A, B, C, ans, R1; scanf ("%d",&N); for(inti =0; i<n; i++) scanf ("%lld%lld",&m[i],&R[i]); A= m[0], r1 = r[0]; for(intI=1; i<n; i++) {b=M[i]; C= R[i]-R1; ll D=gcd (A, b); if(c%d) {ans=-1; Break; } Else{LL A1= A/D; LL B1= bD; LL C1= c/D; EXTEND_GCD (A1,B1); LL X1= (X*C1)%B1; if(x1<0) X1+=B1; R1= A*x1 +R1; A= a1*b; Ans=R1; }} printf ("%lld\n", ans); return 0;}
View Code
Modular linear equation Set