扩展欧几里得算法

贝祖定理:若$a,b$是整数,且
$$gcd(a,b)=d ,$$
  那么对于任意的整数 $x,y$,$ax+by$ 都一定是 $d$ 的倍数。
  特别地,一定存在整数 $x,y$,使 $ax+by=d$ 成立。
  推论$a,b$ 互质的充分必要条件是存在整数 $x,y$ 使 $ax+by=1$ 。

辗转相除法(欧几里得算法)
核心思想:若$a=x_nb+y_nr $,则
$$(a,b)=(b,r) $$
计算公式:
$$\mathrm{gcd}(a,b) = \mathrm{gcd}(b,a\ \mathrm{mod} b) $$
算法:
1 def gcd(a, b):
2     while b != 0:
3          a, b = b, a % b
4 return a
模逆元存在的条件
  • 若 $a,b$ 互素,则 $a$ 必然存在模 $b$ 的逆元;
  • 若 $a,b$ 不互素,则 $a$ 必然不存在模 $b$ 的逆元。

扩展欧几里得算法思想
 
目标:求 $a$ 关于模 $b $ 的逆元。
考虑公式:
$$xa+yb=1 $$
显然$\bm{x} $即为$a$关于模 $b $ 的逆元
由于辗转相除为一个递归的过程,为求得 $x$ ,需要在上述辗转相除法的基础上,需要找到相邻两步中 $\bm{a,b} $ 系数之间的关系
已知最后一步中,若初始的 $a,b$ 互素,则有
$$b==0,\quad a=\mathrm{gcd}(a,b), $$
$$1*a_0+0*b_0={\rm gcd}(a,b), $$
$x_0=1,y_0=0. $

假设 $n-1$ 步中,已知 $a_{n-1},b_{n-1} $ 的系数为 $x_{n-1},y_{n-1}$,即满足
$$x_{n-1}a_{n-1}+y_{n-1}b_{n-1}={\rm gcd}(a,b), $$
由于
$$a_{n-1}=b_n,\quad b_{n-1}=a_n{\rm mod} b_n, $$
代入前一公式,则有
$$\begin{aligned}&x_{n-1}a_{n-1}+y_{n-1}b_{n-1}\\&=x_{n-1}b_n+y_{n-1}(a_n{\rm mod} b_n)\\&=x_{n-1}b_n+y_{n-1}(a_n-(a_n//b_n)*b_n)\\&=y_{n-1}a_n+(x_{n-1}-y_{n-1}*(a_n//b_n))b_n\\&={\rm gcd}(a,b)\end{aligned} $$
则有
$$x_n=y_{n-1},\quad y_n=x_{n-1}-y_{n-1}*(a_n//b_n). $$
其中 $//$ 表示整除。
由于已有 $x_0,y_0 $,按照上述递推公式,可求得 $x_n,y_n $,其中 $x_n $ 即为 $a$ 关于模 $b $ 的逆元

算法实现
 1 def exgcd(a, b, x = 1, y = 0):
 2     """
 3     xa + by = gcd(a, b),求 a,b 的最大公因数
 4     :return: 最大公因数 r 与相应系数 x,y
 5     """
 6     if b == 0:
 7         x = 1
 8         y = 0
 9         return a, x, y
10     r, x, y = exgcd(b, a % b, x, y)
11     temp = y
12     y = x - int(a/b)*y
13     x = temp
14     returnr, x, y
15 
16 def get_moduloInv(a, m):
17     """
18     求 a 关于 m 的模逆元素,即满足 ax+bm=1,即 ax=1(mod m)
19     """
20     gcd, x, y = exgcd(a, m)
21     if gcd != 1:
22         print("a 没有关于 m 的逆元!")
23         returnNone
24     returnx % m
25 
26 print(get_moduloInv(165151, 155454547))
27 """
28 30186144
29 """

 :本文参考自:扩展欧几里得算法详解__Warning_的博客-CSDN博客_扩展欧几里得

posted @ 2022-08-12 10:05  变化的常数  阅读(87)  评论(0)    收藏  举报