GCD

GCD-欧几里得定理(辗转相除)

Elements

\(GCD(a,b)=GCD(b,a\%b)\)

Confirmation

\(a=bk+c\),显然有\(c=a\%b\)。设\(d|a\ \ \ d|b\),则

\[c=a-bk \]

\[\frac{c}{d}=\frac{a}{d}-\frac{b}{d}k \]

由右边的式子可知\(\frac{c}{d}\)为整数,即\(d|c\)所以对于\(a,b\)的公约数,它也会是\(a\%b\)的公约数。

反过来也需要证明

\(d|b\ \ \ d|(a\%b)\),我们还是可以像之前一样得到以下式子

\[\frac{a\%b}{d}=\frac{a}{d}-\frac{b}{d}k \]

\[\frac{a\%b}{d}+\frac{b}{d}k=\frac{a}{d} \]

因为左边式子显然为整数,所以\(\frac{a}{d}\)也为整数,即\(d|a\),所以\(b,a\%b\)的公约数也是\(a,b\)的公约数。

既然两式公约数都是相同的,那么最大公约数也会相同

所以得到式子

\[gcd(a,b)=gcd(b,a\%b) \]

Code

所以我们可以写出一个递归式,层层深入,直到 \(b%(a%b)==0\),即正好为倍数整除时,递归回去就行了

int gcd(int a,int b)
{
	if(b==0)
    	return a;
    return gcd(b,a%b);
}

最后的返回值自然为\(a,b\)的最大公因数

EXGCD-扩展欧几里得定理

目的:求\(ax+by=gcd(a,b)\)的一组可行解
证明

\[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 \]

又因为

\[a\,mod\,b=a-(\lfloor\frac{a}{b}\rfloor*b) \]

所以

\[ax_1+by_1=bx_2+(a-(\lfloor\frac{a}{b}\rfloor*b))y_2 \]

\[ax_1+by_1=ay_2+bx_2-\lfloor\frac{a}{b}\rfloor*by_2=ay_2+b(x_2-\lfloor\frac{a}{b}\rfloor y_2) \]

因为\(a=a,b=b\),所以

\[x_1=y_2 \]

\[y_1=x_2-\lfloor\frac{a}{b}\rfloor y_2 \]

\(x_2,y_2\)不断代入递归求解直至\(GCD\)为0递归\(x=1,y=0\)回去求解,就像\(GCD\)一样的方法

int Exgcd(int a,int b,int &x,int &y)
{
    if (!b) 
    {
        x=1;y=0;
        return a;
    }
    int d=Exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-(a/b)*y;
    return d;
}

返回的值为\(GCD\),在这个过程中计算\(x,y\)即可

posted @ 2019-01-29 13:48  洛水·锦依卫  阅读(327)  评论(0编辑  收藏  举报