GCD与EXGCD

GCD

\(gcd(a,b)\)为a和b的最大公因数,也记为\((a,b)\)
一般用欧几里得算法求解

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

证明(a,b)=(b,c):

设a=bq+c,d为(a,b)
\(d|a, d|b \rightarrow d|c (c=a-bq)\)
\(d|b, d|c \rightarrow d|a (a=bq+c)\)
任何数都是\(0\)的因数因为\(0\cdot x=0\)

复杂度证明:

\(b \leq \frac{a}{2}\),则 \((a,b)=(b,a\)%\(b)\)
\(b > \frac{a}{2}\),则 \((a,b)=(b,a\)%\(b)=(a\)%\(b\)\(b\)%\((a\)%\(b))\)
所以此算法最多经过2遍a就变为原来一半
所以此算法复杂度为\(O(log(min\{a,b\}))\)

ExGcd

展开上述求gcd的递推过程:
\(a=bq_1+r_1\)
\(b=r_1q_2+r_2\)
········
\(r_{k-1}=r_kq_{k+1}+r_{k+1}\)
\(r_k=r_{k+1}q_{k+2}+r_{k+2}\)
\(r_{k+2}=0,r_{k+1}=(a,b)\)
由下往上:
\(1 \cdot r_{k+1} +0 \cdot r_{k+2}=(a,b),r_{k+1}=r_{k-1}-r_kq_{k+1}\)
\(r_{k-1}-r_kq_{k+1}=(a,b),r_k=r_{k-2}-r_{k-1}q_k\)
\((1+q_kq_{k+1})r_{k-1}-q_{k+1}r_{k-2}=(a,b)\)
以此类推,最终能够得到\(ax+by=(a,b)\)的形式
所以若a,b是任意两个不全为0的整数,则存在x,y,使得\(ax+by=(a,b)\)

具体实现:

\(ax+by=(a,b)=(b,a\)%\(b)=bx_1+a\)%\(by_1=bx_1+(a-b \lfloor \frac{a}{b} \rfloor)y_1=ay_1+b(x_1- \lfloor \frac{a}{b} \rfloor y_1)\)
所以\(x=y_1,y=x_1-\lfloor \frac{a}{b} \rfloor y_1\)
特别当\(b=0\)时,\(x_1=1,y_1=0\)

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

注意满足\(ax+by=(a,b)\)\((x,y)\)有无数种解,假设\((x_0,y_0)\)是其中一种解
则所有解为\((x_0+\frac{kb}{(a,b)},y_0-\frac{ka}{(a,b)})(k\in Z)\)

证明:

\(ax_0+by_0=(a,b)\)
\(ax_1+by_1=(a,b)\)
两式相减得到:
\(a(x_0-x_1)+b(y_0-y_1)=0\)
\(a(x_1-x_0)=b(y_0-y_1),设x=x_1-x_0,y=y_0-y_1\)
\(ax=by\)
先求\(x,y\)的最小解
首先可以想到当\(x=b,y=a\)时肯定成立
而最小解\(x<=b\)\(a\)里一定包含一些\(b\)的因数
\(x=\frac{b}{(a,b)}\)时是最小的\(x_{min}\)
同理可得出\(b_{min}=\frac{a}{(a,b)}\)
那么\(ax_{min}k=bky_{min}(k\in Z)\)
所以解得\((x_0+\frac{kb}{(a,b)},y_0-\frac{ka}{(a,b)})(k\in Z)\)

注意
  • \(ax+by=d,d|(a,b)\)
    解为\((\frac{d}{(a,b)}x_0+\frac{kb}{(a,b)},\frac{d}{(a,b)}y_0-\frac{ka}{(a,b)})(k\in Z)\)
  • \((a,b)=1 \Leftrightarrow ax+by=1\)

大整数GCD---Stein算法

posted @ 2021-10-01 19:20  I_N_V  阅读(84)  评论(0编辑  收藏  举报