1. Solving Modular Linear Equations
By ax=b(mod n)
可知ax = ny + b
is equivalent to ax + ny = b
From the extended Euclidean algorithm, it can be known that the solution condition is that gcd(a, n) divides d
The extended Euclidean algorithm can be directly applied
Finally there are d different numbers modulo n when there are d different solutions
2. The Chinese remainder theorem
The proof can be seen: https://www.cnblogs.com/MashiroSky/p/5918158.html
ll extgcd(ll a, ll b, ll& x, ll& y) //求解ax+by=gcd(a, b) //返回值为gcd(a, b) { ll d = a; if(b) { d = extgcd(b, a % b, y, x); y -= (a / b) * x; } else x = 1, y = 0; return d; } ll solve(ll a[], ll m[], int n) // the a array is the remainder, and the m array is a pair of relatively prime numbers { ll M = 1, ans = 0; for(int i = 0; i < n; i++)M *= m[i]; //cout<<M<<endl; for(int i = 0; i < n; i++) { ll mi = M / m[i], x, y; extgcd(mi, m[i], x, y); // Find the inverse of m[i] on the mi module x mi * x + m[i] * y = gcd(mi, m[i]) = 1 (pairwise relative prime) ans = ans + ((a [i] % M) * (mi % M) % M) * (x % M) % M; years = (years % M + M) % M; } return ans; }
3. Extension of Chinese Remainder Theorem --- Solving General Modular Linear Equations
The ordinary Chinese remainder theorem requires all co-primeness, so if not co-prime, how to solve the system of congruence equations?
In this case, the idea of combining two by two is used, assuming that the following two equations are to be combined:
then get:
We need to find a minimum x x that satisfies:
In the code, every time the solution x of m0 * x + m[i] * y = a[i] - a0 is obtained, m[i] is modulo x to ensure that the absolute value of x is small, to prevent overflow from subsequent multiplications,
The general solution for x is x + k * m[i] / gcd(m0, m[i]), where m[i] / gcd(m0, m[i]) is better modulo
1 ll extgcd(ll a, ll b, ll& x, ll& y) 2 //求解ax+by=gcd(a, b) 3 //返回值为gcd(a, b) 4 { 5 ll d = a; 6 if(b) 7 { 8 d = extgcd(b, a % b, y, x); 9 y -= (a / b) * x; 10 } 11 else x = 1, y = 0; 12 return d; 13 } 14 ll solve(ll a[], ll m[], int n)// 15 { 16 ll m0 = m[ 0 ] , a0 = a[ 0 ]; 17 for ( int i = 1 ; i < n; i++ ) 18 { 19 ll x, y; 20 ll g = extgcd(m0, m[i], x, y); // find m0 * x + m[i] * y = gcd(x, y) 21 if ((a[i] - a0) % g) return - 1 ; 22 x = x * (a[i] - a0) / g % m[i]; 23 // find m0 * x + m[i] * y = a[i] - a0 solution x 24 //Here, the modulo m[i] is to take the x with the smallest absolute value, because the general solution of x is x+k*m[i] 25 ll K = x * m0 + a0; // Return to the original formula to find Maximum K 26 m0 = m0 / g * m[i]; // m0 updated to lcm of m0 and m[i] 27 a0 = K; // a0 updated to K 28 a0 = ((a0 % m0) + m0 ) % m0; 29 } 30 return a0; 31 }