Templates - Mathematics - congruence - Extended Euclid Algorithm

Ordinary Extended Euclidean Algorithm, through the valley of Los Extended Euclidean Algorithm to find the multiplicative inverse. Easy fix overflow bug, although the new version still may overflow longlong, if the numbers involved in computing are longlong, if I may use __int128 directly or to copy a RoundGod of BigInt template (where C title). Without further ado large numbers tomorrow to copy this template.
Solving the inverse of a modulo n sense, i.e. of Equation LCE2 (a, 1, n, x), x the result placed in return value indicates whether or not solvable.

ll gcd(ll a, ll b) {
    if(b == 0)
        return a;
    while(ll t = a % b)
        a = b, b = t;
    return b;
}

ll ex_gcd(ll a, ll b, ll& x, ll& y) {
    if(b == 0) {
        x = 1, y = 0;
        return a;
    }
    ll d = ex_gcd(b, a % b, x, y), t;
    t = x, x = y, y = t - a / b * y;
    return d;
}

//解线性同余方程 ax + by = c ,无解返回false
bool LCE1(ll a, ll b, ll c, ll &x0, ll &y0) {
    ll x, y, d = ex_gcd(a, b, x, y);
    if(c % d)
        return false;
    ll k = b / gcd(a, b);
    x0 = ((x % k) * (c / d % k) % k + k) % k;
    y0 = (c - a * x0) / b;
    //x0是x的最小非负整数解
    //x=x0+b*t,y=y0-a*t,是方程的所有解,对所有整数t成立
    return true;
}

//解线性同余方程 ax = b mod n ,无解返回false
//和方程 ax + ny = b 等价
bool LCE2(ll a, ll b, ll n, ll &x0) {
    ll x, y;
    if(LCE1(a, n, b, x, y)) {
        ll k = n / gcd(a, n);
        x0 = (x % k + k) % k;
        //x0是最小非负整数解
        //x=x0+k*t,是方程的所有解,对所有整数t成立
        return true;
    } else
        return false;
}

Unrepaired version will be faster in theory constant, unnecessary. But still be a reminder:

//解线性同余方程 ax + by = c ,无解返回false
bool LCE1(ll a, ll b, ll c, ll &x0, ll &y0) {
    ll x, y, d = ex_gcd(a, b, x, y);
    if(c % d)
        return false;
    ll k = c / d;
    x0 = x * k;
    y0 = y * k;
    //x=x0+b*t,y=y0-a*t,是方程的所有解,对所有整数t成立
    return true;
}

Guess you like

Origin www.cnblogs.com/KisekiPurin2019/p/11886449.html