1 条题解

  • 4
    @ 2025-3-9 21:29:36

    普及一点小学数学知识。

    辗转相减法

    Lemma 1\bold {Lemma\space1}

    对于 a>ba>bgcd(a,b)=gcd(ab,b)\gcd(a,b)=\gcd(a-b,b)

    Proof\bold{Proof}

    g=gcd(a,b)g=\gcd(a,b),则 a=pg,b=qga=pg,b=qg。那么 ab=(pq)ga-b=(p-q)g。因此 gcd(ab,b)g\gcd(a-b,b)\ge g

    同理,令 h=gcd(ab,b)h=\gcd(a-b,b),则 ab=ph,b=qha-b=ph,b=qh。那么 a=(p+q)ha=(p+q)h。因此 gcd(a,b)h\gcd(a,b)\ge h

    所以 gcd(a,b)=gcd(a,b)\gcd(a,b)=\gcd(a,b)

    Q.E.D.\mathcal{Q.E.D.}

    辗转相除法

    Lemma 2\bold{Lemma\space 2}

    对于 a>ba>b,有 gcd(a,b)=gcd(amodb,b)\gcd(a,b)=\gcd(a\bmod b,b)

    Proof\bold{Proof}

    a=kb+ra=kb+r,则 gcd(amodb,b)=gcd(r,b)\gcd(a\bmod b,b)=\gcd(r,b)。而 aarr 的过程即减去 kkbb。每一次减 bb 都保证 gcd\gcd 相等。所以 gcd(a,b)=gcd(amodb,b)\gcd(a,b)=\gcd(a\bmod b,b)

    Q.E.D.\mathcal{Q.E.D.}

    那么 gcd 就可以这么写:

    def gcd(a, b):
      if b == 0:
        return a
      else:
        return gcd(b, a % b)
    

    注意到 if 语句中,若 b=0b=0,则考虑上一轮的 a,ba,b 一定满足 aabb 的倍数。此时应返回上一轮的 bb,而这正好就是这轮的 aa

    但是我们怎么保证一定会进入这个 if 终止递归呢?

    我们考虑递推定义如下的二元组序列 (ai,bi)(a_i,b_i):对于 i2i\ge 2(ai,bi)=(bi1,ai1modbi1)(a_i,b_i)=(b_{i-1},a_{i-1}\bmod b_{i-1})。容易发现每个 gcd(a[i], b[i]) 会调用 gcd(a[i + 1], b[i + 1])

    称两个二元组 (x,y),(p,q)(x,y),(p,q) 相等,当且仅当 x=px=py=qy=q

    我们断言:存在一个有限的 kk,使得 bk=0b_k=0

    证明这个结论还需要一个引理。

    Lemma 3\bold{Lemma\space 3}

    对于任意正整数 aa,满足对于任意 b[1,a]b\in [1,a]amodba2a\bmod b\le \left\lfloor\dfrac{a}{2}\right\rfloor

    Proof\bold{Proof}

    若 $b\in \left[1,\left\lfloor\dfrac{a}{2}\right\rfloor+1\right]$,显然成立。否则,$a\bmod b=a-b\le \left\lfloor\dfrac{a}{2}\right\rfloor$。

    Q.E.D.\mathcal{Q.E.D.}

    考虑构造一个新的二元组序列 (ui,vi)(u_i,v_i),满足:(u1,v1)=(a1,b1)(u_1,v_1)=(a_1,b_1);对于 i2i\ge 2,$(u_i,v_i)=\left(v_{i-1},\left\lfloor\dfrac{u_{i-1}}{2}\right\rfloor\right)$。那么容易得知对于 i3i\ge 3vi=vi22v_i=\left\lfloor\dfrac{v_{i-2}}{2}\right\rfloor。由此可以得知 v2log2b1+1+1=0v_{2\lfloor\log_2b_1+1\rfloor+1}=0。令 k=2log2b1+1+1k=2\lfloor\log_2b_1+1\rfloor+1

    通过 Lemma 3\bold{Lemma\space 3},不难把除以 22 下取整和取模联系在一起。

    Lemma 4\bold{Lemma\space 4}

    对于任意正整数 ii,有 aiuia_i\le u_ibivib_i\le v_i

    Proof\bold{Proof}

    考虑使用归纳法。当 i=1i=1 时显然成立。

    若当 i[1,m]i\in[1,m] 时成立。则对于 mmamuma_m\le u_mbmvmb_m\le v_m。当 i=m+1i=m+1 时,ai=bma_{i}=b_mui=vmu_i=v_m,因此 aiuia_i\le u_i;$b_i=a_m\bmod b_m\le \left\lfloor\dfrac{a_m}{2}\right\rfloor\le \left\lfloor\dfrac{u_m}{2}\right\rfloor$,vi=um2v_i=\left\lfloor\dfrac{u_m}{2}\right\rfloor,因此 bivib_i\le v_i。所以在 i[1,m+1]i\in[1,m+1] 时仍然成立。

    综上,对于任意正整数 ii,有 aiuia_i\le u_ibivib_i\le v_i

    Q.E.D.\mathcal{Q.E.D.}

    由此得知 bkvk0b_k\le v_k\le 0。而容易发现 bib_i 恒非负。因此 bk=0b_k=0

    所以我们可以断言:存在一个有限的 kk,使得 bk=0b_k=0

    而且我们还分析出来满足上述条件的最小的 kk 满足 k=O(logb1)k=\mathcal{O}(\log b_1)。因此,辗转相除法求两个数 a,ba,b 最大公约数的时间复杂度为 O(logn)\mathcal{O}(\log n),其中认为 max{a,b}=O(n)\max\{a,b\}=\mathcal{O}(n)

    • 1

    信息

    ID
    240
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    19
    已通过
    5
    上传者