扩展欧几里得

对于方程 ax+by=c(x,y为整数),当且仅当 c%gcd(a,b)==0 时,(x,y)有解(见证明3),且有gcd(a,b)组解。

求出方程的一个解x,方程的最小正整数解x0 = (x%(b/gcd(a,b) ) + b/gcd(a,b)) % b/gcd(a,b) (见证明4)

那么 exgcd(int a,int b,int &x,int &y)为求解该方程的函数,这个函数的返回值为 gcd(x,y),代码如下

int exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x = 1; //解释见证明1
        y = 0; //解释见证明1
        return a;
    }

    else
    {
        int r = exgcd(b,a%b,y,x);  //解释见证明2
        y -= a/b*x;  //解释见证明2
        return r;
    }
}

相关证明:

  证明1:当b=0时,gcd(a,b)= a,那么有 ax=a, 得x=1,y=0。

  证明2:有裴蜀定理得知:a*x1 + b*y1 = gcd(a,b) 一定成立,

       那么得:b*x2 + (a%b)*y2 = gcd(a,b) 

       那么得:b*x2 + (a - a/b*b)*y2 = gcd(a,b)

       那么得:b*x2 + a*y2 - a/b*y2*b = gcd(a,b)

       那么得:a*y2 + b(x2 - a/b*y2) = gcd(a,b)

       因为:a*x1 + b*y1 = gcd(a,b)

       所以: x1= y2,y1 = (x2 - a/b*y2)

  证明3: 结论 对于方程 ax+by=c(x,y为整数),当且仅当 c%gcd(a,b)==0 时有解

      设 f = c mod (gcd(a,b)),那么f的取值范围应为 : 0 <= f < gcd(a,b)

      有裴蜀定理知道:ax + by = gcd(a,b)

      可设:k*gcd(a,b) + f = c

      那么:k*a*x + k*b*y + f = c

      若 f != 0,因为0 <= f < gcd(a,b),所以 f = m*a(m为整数)不成立,所以 k*a*x + k*b*y + ma = c 不成立

      所以 f应为0,那么 c mod (gcd(a,b)) 应为 0。

  证明4:设c = gcd(a,b),相邻的两组解之间的间隔为dx

      得:a*x = d(mod b),

        a*(x+dx) = d(mod b)

      两个式子相减得 : a*dx % b  = 0

      a*dx 是b的整数倍,也是a的整数倍,所以lcm(a,b)所对应的dx值最小

      lcm(a,b) = a*b/c

      所以 a*dx = a*b/c,所以 dx = b/c

      所以最小解x0为:(x%dx + dx)%dx,(x为已经求出的一个解)

原文地址:https://www.cnblogs.com/alan-W/p/7241259.html