初等数论--欧几里得算法
1. 定义
u 0 u 1 ∈ Z , u 1 ≠ 0 , u 1 ∤ u 0 u_0\ u_1\in Z,u_1 \ne0,u_1 \nmid u_0 u0 u1∈Z,u1=0,u1∤u0
根据带余除法可得下面一系列等式
u 0 = q 0 u 1 + u 2 0 < u 2 < ∣ u 1 ∣ u 1 = q 0 u 2 + u 3 0 < u 3 < u 2 ⋯ u k − 1 = q k − 1 u k + u k + 1 0 < u k < u k u k = q k u k + 1 \begin{align*} u_0 &=q_0u_1+u_2\quad 0 < u_2 <\lvert u_1\rvert\\ u_1 &=q_0u_2+u_3\quad 0 < u_3 < u_2\\ \cdots \\ u_{k-1} &=q_{k-1}u_k + u_{k+1}\quad 0 < u_k <u_{k}\\ u_k &=q_ku_{k+1} \end{align*} u0u1⋯uk−1uk=q0u1+u20<u2<∣u1∣=q0u2+u30<u3<u2=qk−1uk+uk+10<uk<uk=qkuk+1
我们可以得到
0 < u k + 1 < u k < ⋯ < u 2 < ∣ u 1 ∣ 0 <u_{k+1} <u_k <\cdots<u_2 < \lvert u_1\rvert 0<uk+1<uk<⋯<u2<∣u1∣
由于小于 ∣ u 1 ∣ |u_1| ∣u1∣的正整数只有有限个,所以上面的过
程必定有限。
也就是要么 1 ≠ u k + 1 ∣ u k 1 \ne u_{k+1}\mid u_k 1=uk+1∣uk, 要么 1 = u k + 1 ∣ u k 1 = u_{k+1} \mid u_k 1=uk+1∣uk。
2. 结论
2.1 最大公因数
u k + 1 u_{k+1} uk+1为 u 0 u 1 u_0\ u_1 u0 u1的最大公因数。
引理1
∀ a , b ∈ Z ⇒ ∀ x ∈ Z , gcd ( a , b ) = gcd ( a , b + a x ) \forall a,b \in Z \Rightarrow\\ \forall x \in Z,\gcd(a,b)=\gcd(a,b+ax) ∀a,b∈Z⇒∀x∈Z,gcd(a,b)=gcd(a,b+ax)
运用该引理我们可以得到
gcd ( u 0 , u 1 ) = gcd ( u 1 , u 2 ) = ⋯ = gcd ( u k , u k + 1 ) = u k + 1 \gcd(u_0,u_1)=\gcd(u_1,u_2)=\cdots=\\\gcd (u_k,u_{k+1})=u_{k+1} gcd(u0,u1)=gcd(u1,u2)=⋯=gcd(uk,uk+1)=uk+1
2.2 裴祖系数的存在性
∃ x 0 , x 1 ∈ Z , s . t . x 0 u 0 + x 1 u 1 = gcd ( u 0 , u 1 ) = u k + 1 \exists x_0,x_1 \in Z, s.t. \quad \\x_0u_0+x_1u_1=\gcd(u_0,u_1)=u_{k+1} ∃x0,x1∈Z,s.t.x0u0+x1u1=gcd(u0,u1)=uk+1
根据辗转相除法的等式,我们可以从直觉上看出 u 0 , u 1 u_0,u_1 u0,u1的线性组合可以表示 u k + 1 u_{k+1} uk+1。
我们可以观察到下面的递推式:
[ u t + 1 u t ] = [ − q t − 1 1 1 0 ] [ u t u t − 1 ] \begin{bmatrix} u_{t+1}\\u_{t} \end{bmatrix}= \begin{bmatrix} -q_{t-1} & 1 \\ 1 & 0 \end{bmatrix} \begin{bmatrix} u_{t}\\u_{t-1} \end{bmatrix} [ut+1ut]=[−qt−1110][utut−1]
因此容易得到
[ u k + 1 u k ] = [ − q k − 1 1 1 0 ] ⋯ [ − q 0 1 1 0 ] [ u 1 u 0 ] \begin{bmatrix} u_{k+1}\\u_{k} \end{bmatrix}=\\ \begin{bmatrix} -q_{k-1} & 1 \\ 1 & 0 \end{bmatrix} \cdots \begin{bmatrix} -q_{0} & 1 \\ 1 & 0 \end{bmatrix} \begin{bmatrix} u_{1}\\u_{0} \end{bmatrix} [uk+1uk]=[−qk−1110]⋯[−q0110][u1u0]
2.2 引理1证明
首先 g c d ( a , b ) = g c d ( − a , b ) = g c d ( a , − b ) = g c d ( ∣ a ∣ , ∣ b ∣ ) gcd(a,b) =gcd(-a,b)=gcd(a,-b)=gcd(|a|,|b|) gcd(a,b)=gcd(−a,b)=gcd(a,−b)=gcd(∣a∣,∣b∣)。
因此我们只需要考虑 a , b > 0 a,b>0 a,b>0的情况。
容易得到 g c d ( a , b ) < min ( a , b ) gcd(a,b)< \min(a,b) gcd(a,b)<min(a,b),
又 g c d ( a x , a ) = a gcd(ax,a)=a gcd(ax,a)=a,即 ∀ d ∣ a ⇒ d ∣ a x \forall d \mid a \Rightarrow d \mid ax ∀d∣a⇒d∣ax.
因此 ∀ d ∣ a , d ∣ b + a x ⇔ ∀ d ∣ a , d ∣ b \forall d \mid a,d \mid b+ax \Leftrightarrow \forall d \mid a,d \mid b ∀d∣a,d∣b+ax⇔∀d∣a,d∣b
即 g c d ( a , b ) = g c d ( a , b + a x ) gcd(a,b) = gcd(a,b+ax) gcd(a,b)=gcd(a,b+ax)
3. 实现
- 递归
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);
}
- 迭代
int gcd_fast(int a, int b) {while (b) {int tmp = b;b = a % b;if (2 * b > tmp)b = tmp - b;a = tmp;}return a;
}
参考
初等数论