扩展欧几里得算法
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,ab!=0 时
$$ax_1+by_1=\gcd(a,b)$$
$$bx_2+(a \mod b)y_2=\gcd(b,a \mod b) $$
因为$\gcd(a,b)==\gcd(b,a \mod b)$
所以$ax_1+by_1=bx_2+(a \mod b)y_2$
$ax_1+by_1=bx_2+(a - \frac{a}{b} \times b )y_2$ 注:这里的a/b 是整除
$ax_1+by_1 = bx_2+(a \times y_2 - \frac{a}{b} \times b \times y_2 )$
$ax_1+by_1 = a \times y_2 + bx_2 - \frac{a}{b} \times b \times y_2$
所以求出通解
$$ x_1=y_2 $$
$$ y_1=x_2 - \frac{a}{b} \times y_2 $$
逆元
扩展欧几里得算法有什么用呢? 最大的作用就是求逆元。
什么叫做逆元?
这里,我们称 x 是 a 关于 m 的乘法逆元
这怎么求?首先a必须与m互质(充要条件) 即gcd(a,m)=1 为什么? 因为如果 a可以被m整除的话 那么a mod m必为0
根据gcd(a,m)=1 可以得出 ax+my=1 ,这时候用 扩展欧几里得算法 就可以求出x的值了。
但是 大部分题目要求 x是最小正整数解
这个时候就需要 (x+m)%m了。因为x有可能是负数
证明一下 (x+m)%m 不会证明....


1 #include <cstdio> 2 typedef long long ll; 3 ll a,b,x,y; 4 ll ex_gcd(ll a,ll b,ll &x,ll &y){ 5 if(!b){ 6 x=1; 7 y=0; 8 return a; 9 } 10 ll ans = ex_gcd(b,a%b,x,y); 11 ll num = x; 12 x = y; 13 y = num - (a/b)*y; 14 return ans; 15 } 16 17 int main(){ 18 scanf("%lld%lld",&a,&b); 19 ex_gcd(a,b,x,y); 20 printf("%lld",(x+b)%b); 21 return 0; 22 }