Modular Linear Equation && Chinese Remainder Theorem and Its Extension

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 }

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326710993&siteId=291194637