• 扩展欧几里得


    对于方程 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为已经求出的一个解)

  • 相关阅读:
    [Codeforces Round #516][Codeforces 1063C/1064E. Dwarves, Hats and Extrasensory Abilities]
    接入gitment为hexo添加评论功能
    常用SQL语句
    小米前端二面面经
    将hexo的评论系统由gitment改为Valine
    同步与异步
    前端构建工具对比
    前端向后台发送请求有哪些方式
    关于hexo markdown添加的图片在github page中无法显示的问题
    使用TensorBoard可视化工具
  • 原文地址:https://www.cnblogs.com/alan-W/p/7241259.html
Copyright © 2020-2023  润新知