Grade 12 · Math for programmingCitește în română

Extended Euclidean algorithm

Original: Algoritmul lui Euclid extins

O(log n)C++1756 lines2 examples

The idea

Besides d = gcd(a, b), we find integers x and y with a * x + b * y = d. If b = 0, then d = a, x = 1, y = 0. Otherwise we solve recursively for (b, a % b) and get x1, y1 with b * x1 + (a % b) * y1 = d. Since a % b = a - (a / b) * b, it follows that x = y1 and y = x1 - (a / b) * y1. If d = 1, x (brought into [0, b)) is the inverse of a modulo b. The program prints d, x, y, then the inverse or the message 'nu exista' (does not exist).

Original description (Romanian)

Pe lângă d = cmmdc(a, b), găsim numere întregi x și y cu a * x + b * y = d. Dacă b = 0, atunci d = a, x = 1, y = 0. Altfel rezolvăm recursiv pentru (b, a % b) și obținem x1, y1 cu b * x1 + (a % b) * y1 = d. Cum a % b = a - (a / b) * b, rezultă x = y1 și y = x1 - (a / b) * y1. Dacă d = 1, x (adus în [0, b)) este inversul lui a modulo b. Programul afișează d, x, y, apoi inversul sau mesajul „nu exista”.

Complexity
O(log min(a, b))
Grade
Grade 12 (Clasa a XII-a)

Examples

Example 1

Input

30 18

Expected output

6 -1 2
nu exista
Example 2

Input

3 11

Expected output

1 4 -1
4

The code

Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.

euclid-extins.cpp
/*
 * Titlu: Algoritmul lui Euclid extins
 * Clasa: 12
 * Capitol: Matematică pentru programare
 * Descriere: Pe lângă d = cmmdc(a, b), găsim numere întregi x și y cu
 *            a * x + b * y = d. Dacă b = 0, atunci d = a, x = 1, y = 0. Altfel
 *            rezolvăm recursiv pentru (b, a % b) și obținem x1, y1 cu
 *            b * x1 + (a % b) * y1 = d. Cum a % b = a - (a / b) * b, rezultă
 *            x = y1 și y = x1 - (a / b) * y1. Dacă d = 1, x (adus în [0, b)) este
 *            inversul lui a modulo b. Programul afișează d, x, y, apoi inversul
 *            sau mesajul „nu exista”.
 * Complexitate: O(log min(a, b))
 *
 * Exemplu
 * Intrare: 30 18
 * Ieșire:
 * 6 -1 2
 * nu exista
 *
 * Exemplu
 * Intrare: 3 11
 * Ieșire:
 * 1 4 -1
 * 4
 */
#include <iostream>
using namespace std;

long long euclidExtins(long long a, long long b, long long &x, long long &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    long long x1, y1;
    long long d = euclidExtins(b, a % b, x1, y1);
    x = y1;
    y = x1 - (a / b) * y1;
    return d;
}

int main()
{
    long long a, b, x, y;
    cin >> a >> b;
    long long d = euclidExtins(a, b, x, y);
    cout << d << ' ' << x << ' ' << y << '\n';
    if (d == 1)
        cout << ((x % b) + b) % b << '\n';
    else
        cout << "nu exista\n";
    return 0;
}

Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.