再探最大公约数

\[\newcommand{\lcm}{\mathrm{lcm}\,} \]

说明: 在不定方程之前,数集指的是正整数集; 全文以 \(\%\) 表示取模运算。

从更相减损术说起

可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。

最小公倍数定义为最大的 \(a\) ,使得 \(a|b\)\(a|c\) 。记 \(\gcd(b,c)=a\)

那么更相减损术就是说 \(\gcd(a,b)=\gcd(a-b,b)\)\(a>b\) ); \(\gcd(a,b)=a=b\) ,并且迭代有限次数后,一定能得到 \(a=b\) 的情况。

  • 感性理解
    \(a\)\(b\) 都是由长度为 \(\gcd(a,b)\) 的块组成的。那么减一减一定还是 \(\gcd(a,b)\) 长的块的整数倍。

  • 证明
    \(a\)\(b\) 相等情况证明略,操作步数有限性证明略。
    \(\gcd(a,b)=k\) ,那么 \(a=a'k\)\(b=b'k\) 。由于 \(a>b\) ,所以 \(a'>b'\) 。那么 \(a - b=(a'-b')k\neq 0\) 。所以 \(k|a-b\) ,那么 \(\gcd(a-b,b)\geqslant k\)
    而若 \(\gcd(a-b,b)>k\) ,那么存在 \(k'>1\) ,使得 \(kk'|b\)\(kk'|a-b\) 。那么 \(k'|b\)\(k'|a-b\) 。那么 \(k'|(a-b)+b\) ,即 \(k'|a\) 。所以 \(kk'|a\)\(kk'|b\)\(kk'>k\) 。这与 \(\gcd\) 的最大性矛盾。所以 \(\gcd(a-b,b)\leqslant \gcd(a,b)\)
    综上所述, \(\gcd(a-b,b)=\gcd(a,b)\)

更快的实现:辗转相除法

\(a\) 远大于 \(b\) 的时候,更相减损术会花很多的时间让 \(a\) 不断地减去 \(b\) 。我们可以想办法加速这个过程——即用取余操作代替减法操作。
辗转相除法可以这样描述 :

假设 \(a\geqslant b\) ,那么 \(\gcd(a,b)=\gcd(b,a\%b)\)\(b\nmid a\)\(\gcd(a,b)=b\)\(b|a\)

而由于 \(a\%b \leqslant \lfloor\frac{a}{2}\rfloor\) ,所以辗转相除法的时间复杂度是 \(\log\) 级别的。

int Gcd(int a, int b)
{
    if(a % b == 0) return a;
    return Gcd(b, a % b);
}
int Gcd(int a, int b)
{
    int m = a % b;
    while (m)
    {
        a = b;
        b = m;
        m = a % b;
    }
    return b;
}

最大公约数的性质:裴蜀定理

裴蜀定理(或贝祖定理,Bézout's identity)得名于法国数学家艾蒂安·裴蜀。说明了对任何整数 \(a\)\(b\) 和它们的最大公约数 \(d\) :若 \(a\) , \(b\) 是整数,且 \(\gcd(a,b)=k\) ,那么对于任意的整数 \(x\)\(y\) , \(ax+by\) 都一定是 \(k\) 的倍数;特别地,一定存在整数 \(x\) , \(y\) ,使 \(ax+by=k\) 成立。

证明:
\(\gcd(a,b)=k\) ,所以 \(k|a\)\(k|b\) 。由整除的性质,对于任意 \(x,y\in Z\)\(k|ax+by\)
\(ax+by\) 的最小正整数值为 \(s\)\(q = \lfloor\frac{a}{s}\rfloor\)\(r=a \% s=a-q(ax+by)=a(1-qx)+b(-qy)\)。也就是说, \(r\) 也是 \(ax+by\) 的某个取值。而由于 \(s\) 的最小性,\(r=0\) 。即 \(s|a\) 。同样的,有 \(s|b\) 。又因为 \(ax+by\)\(k\) 的倍数,所以 \(s=k\)

如何构造这样一组解?:扩展欧几里得算法

\(b|a\) 时, \(\gcd(a,b)=b\)\(x=0,y=1\) 是方程 \(ax+by=b\) 的一组解。
如果我们已经知道了 \(x',y'\) 是方程 \(bx+(a\%b)y=\gcd(a,b)\) 的一组解,那么有:

\[bx'+(a-b\lfloor\frac{a}{b}\rfloor)y'=\gcd(a,b)\\ bx'+ay'-b\lfloor\frac{a}{b}\rfloor y'=\gcd(a,b)\\ ay'+b(x'-\lfloor\frac{a}{b}\rfloor x')=\gcd(a,b) \]

\(x=y'\)\(y=x'-\lfloor\frac{a}{b}\rfloor x'\) 就能得到 \(ax+by=\gcd(a,b)\) 的一组解。

void exgcd(int a, int b, int &x, int &y, int &gcd)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        gcd = a;
        return;
    }
    exgcd(b, a % b, y, x, gcd);
    y -= a / b * x;
    return;
}

不定方程 \(ax+by=c\) 的最小整数解

通解形式

显然,如果 \(\gcd(a,b) \nmid c\) ,方程无解。

先考虑方程 \(ax+by=\gcd(a,b)\) 。为了让 \(ax+by=\gcd(a,b)\)\(ax\)\(by\) 的值要同时变化 \(\lcm(a,b)\) 。所以通解为

\[x=x'+k\frac{b}{\gcd(a,b)}\\ y=y'-k\frac{a}{\gcd(a,b)} \]

其中 \(x'\)\(y'\) 是一组特解。
\(p=\frac{b}{\gcd(a,b)}\) 那么 \(x=(x' \% p +p ) \%p\) 就是 \(x\) 的最小正整数解。

然后在看方程 \(ax+by=c\) 。不难发现它的通解是

\[x=x'\frac{c}{\gcd(a,b)}+k\frac{b}{\gcd(a,b)}\\ y=y'\frac{c}{\gcd(a,b)}+k\frac{a}{\gcd(a,b)} \]

同样的,令 \(p=\frac{b}{\gcd(a,b)}\) 。为了防止溢出,可以这样算:

\[x=(x'\%p)\times(\frac{c}{\gcd(a,b)}) \% p \]

最后 \(x\) 可能为负数,所以 \(x=(x+p)\%p\) 即可。

扩展欧几里得算法的应用:乘法逆元

我的博客

推荐练习题

CF1244C The Football Season

posted @ 2019-10-18 20:00  chy_2003  阅读(130)  评论(0编辑  收藏  举报