数论复习(gcd)

gcd

  • gcd有两种求法:gcd(a, b)=gcd(b, a%b)=gcd(a-b, b)

扩展gcd(一种新的写法)

  • 找出一对整数\((x, y)\)使得\(ax+by=gcd(a,b)\)
void exgcd(int a, int b, int &x, int &y)
{
    if(!b)
    {
        x = 1;
        y = 0;
        return ;
    }
    exgcd(b, a%b, y, x);//x'=y, y'=x
    y-=(a/b)*x;
    return ;
}
  • 代码如上,但是这是如何得出的呢?我们来推导一下
  • \(ax+by=d, bx'+(a mod b)y'=d\)
    \(bx'+(a-\left\lfloor\frac{a}{b}\right\rfloor·b)y'=d\)
    \(bx'+ay'-\left\lfloor\frac{a}{b}\right\rfloor·by'=d\)
    \(ay'+b(x'-\left\lfloor\frac{a}{b}\right\rfloor·y')=d\)
    \(x=y', y=x'-\left\lfloor\frac{a}{b}\right\rfloor·y'\)
  • 然后就变成了求\(bx'+(a mod b)y'=d\)
  • 坚持不懈的递归下去,总能找到b=0的时候,然后就能求x'和y',再代回去就OK啦!
  • 不理解也没问题,老师说代码背会就OK!
  • 上面那个好背哦,但是难理解,下面这个就是【真·直译】
void exgcd(int a, int b, int &x, int &y)
{
    if(!b)
    {
        x = 1;
        y = 0;
        return ;
    }
    exgcd(b, a%b, x, y);
    int temp;
    temp = x;
    x = y;
    y = temp-(a/b)*y;
    return ;
}
  • OK完美!但是只有这样吗?
  • 当然不是。解不一定只有这一种,为了求出更多的解:\(ax_1+by_1=ax_2+by_2=d\)
    移项\(\Rightarrow a(x_1-x_2)=b(y_2-y_1)\)
    除d\(\Rightarrow a'(x_1-x_2)=b'(y_2-y_1), a'=a/d, b'=b/d\)
    显然,a'与b'互质,\(\therefore x_1-x_2=kb', y_2-y_1=ka'\)
    \(\therefore x_2=x_1-kb', y_2=y_1+ka'(k\in Z)\)

客串一个裴蜀定理

  • \(ax+by=c\)有解,当且仅当\(gcd(a, b)|c\)
    \(c=gcd(a,b)·k\),两边同除k得\(a(x/k)+b(y/k)=gcd(a,b)\)
    \(x'=x/k, y'=b/k; \therefore ax'+by'=gcd(a,b)\)
    显然我们能求出\(x', y'\),因此也能求出原来的解。

猜你喜欢

转载自www.cnblogs.com/orange-233/p/12386810.html