zoukankan      html  css  js  c++  java
  • 极度精简好理解的exgcd

    前言

    本文通过尽量短,通俗易懂的形式帮助大家理解最简单的 exgcd。

    前置知识:

    裴蜀定理:

    [ax+by=c,xin mathbb{Z}^*,yin mathbb{Z}^*有解的充要条件是gcd (a,b)|c ]

    欧几里得算法(辗转相除法)

    [gcd(a,b)=gcd(b,amod b) (b eq 0) ]

    模运算的本质:

    [amod b = a - leftlfloor frac{a}{b} ight floor b ]

    其中 (leftlfloor frac{a}{b} ight floor) 指的是 (frac{a}{b}) 下取整。

    正片:

    exgcd,扩展欧几里得,扩欧,是求下面这个不定方程解的方法:

    [ax+by=gcd(a,b) ]

    把后面的 (gcd(a,b)) 辗转相除一下再写成类似的形式(这里的 (x',y') 是对应 (gcd(b,amod b))(x,y),和上面的 (x,y) 没有关系):

    [bx'+(amod b)y'=gcd(b,amod b) ]

    [ax+by=gcd(a,b)=gcd(b,amod b)=bx'+(a-leftlfloorfrac{a}{b} ight floor b)y' ]

    [ax+by=bx'+(a-leftlfloorfrac{a}{b} ight floor b)y' ]

    因为要求解 (x,y),所以假设我们已经求解了 (x',y'),则要按 (a,b) 把两个方程分开,然后就可以递归求解了。(貌似没有为什么,就是这么处理然后是可以递归求解的)

    [ax+by=ay'+b(x'-leftlfloor frac{a}{b} ight floor y') ]

    解出 (x,y) 就要求解 (x'y'),注意求解 (x'y') 的时候,他们对应的 (a,b) 实际上是原先 (x,y)(a,b)(b,amod b)

    递归就能求出 (ax+by=gcd(a,b)) 一组特解了,最后当 (b=0) 的时候递归终止,此时 (ax+by=gcd(a,b)) 的解显然是 (x=1,y=0)(0) 和非零数的 (gcd) 仍为那个数本身)。

    (mathcal{Code})

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

    后记

    这样最基础的 exgcd 就到这里了,如果想进一步理解更深层的 exgcd,推荐阅读:

    洛谷日报#288 [_Leaving]同余方程-5天从入门到入土

    本文参考文章

  • 相关阅读:
    vue工程项目中配置测试环境及生产环境线上地址
    复杂表格的拖拉拽,及行列拖拽
    前端骨架屏的资料
    关于vue中的重复key的警告问题
    git 约定规范
    git 博客
    关于svg的一些事
    vue单文件组件2(webpack打包)
    vue单文件组件1(webpack打包)
    vue-resource
  • 原文地址:https://www.cnblogs.com/do-while-true/p/13917731.html
Copyright © 2011-2022 走看看