## Thuật toán Euclid Thuật toán Euclid tính $\gcd(a, b)$: $$\gcd(a, b) = \begin{cases}a &\text{nếu }b = 0 \\ \gcd(b, a \bmod b) &\text{nếu }b \neq 0 \end{cases}$$ ```cpp! int gcd(int a, int b) { if(b == 0) return a; return gcd(b, a % b); } ``` ## Thuật toán Euclid mở rộng Thuật toán Euclid mở rộng ngoài tính gcd của 2 số ra còn tính được 2 hệ số $x$ và $y$ sao cho: $$a \cdot x + b \cdot y = \gcd(a, b)$$ ### Thuật toán Gọi $\gcd(a, b)$ là $g$. Trong thuật toán Euclid, khi gặp trường hợp $b = 0$, vậy khi đó $a = g$ và $b = 0 \Rightarrow a \cdot x + b \cdot y = g \iff g \cdot x + 0 \cdot y = g \Rightarrow x = 1, y = 0$ Vậy $x = 1, y = 0$ trong base case. Ta có $\gcd(a, b) = \gcd(b, a \bmod b) = g$. Giả sử ta đã tìm được $x_1$ và $y_1$ là cặp $x, y$ đối với $\gcd(b, a \bmod b)$. Nói cách khác, đã tìm được $x_1, y_1$ sao cho $b \cdot x_1 + (a \bmod b) \cdot y_1 = g$ Đầu tiên, ta viết lại $a \bmod b$ thành $a - \left\lfloor {a \over b} \right\rfloor \cdot b$: $$b \cdot x_1 + \left(a - \left\lfloor {a \over b} \right\rfloor \cdot b\right) \cdot y_1 = g$$ Tách ra: $$b \cdot x_1 + a \cdot y_1 - \left\lfloor {a \over b} \right\rfloor \cdot b \cdot y_1 = g$$ Lấy $b$ làm nhân tử chung: $$a \cdot y_1 + b \cdot \left(x_1 - \left\lfloor {a \over b} \right\rfloor \cdot y_1\right) = g$$ Vậy ta đã tìm được cặp hệ số $x, y$ đối với $a, b$: $$\begin{cases} x = y_1 \\ y = x_1 - \left\lfloor{a \over b}\right\rfloor \cdot y_1 \end{cases}$$ ```cpp! int extended_euclidean(int a, int b, int& x, int& y) { if(b == 0) { x = 1; y = 0; return a; } int x1, y1; int g = extended_euclidean(b, a % b, x1, y1); x = y1; y = x1 - (a / b) * y1; return g; } ```