1 window.cnblogsConfig = { 2 homeBannerTextType: "one", //one为每日一句话,若采用homBannerText自己设置,则显示自己设置标语优先显示 3 } 4 5 /** 所有可配置项 6 jinrishici:每次刷新随机获取一句古诗词。 7 one:每日获取一句话 8 */

exgcd再整理

发现自己是个sb,exgcd学了不知多少遍还是忘,故整理此文

欧几里得算法

用于计算两个整数a,b的最大公约数

定理:$\gcd(a,b)=\gcd(b,a\bmod b)$

证明:$a$可以表示成$a=kb+r$,其中$r=a\bmod b$

1、假设$d$是$a$,$b$的一个公约数,则有:

$d\mid a$,$d\mid b$,而$r=a-kb$,因此$d\mid r$

因此$d$是$(b,a\bmod b)$的公约数

2、假设$d$是$(b,a\bmod b)$的公约数,则有:

$d\mid b$,$d\mid r$,同时$a=kb+r$

因此$d$也是$a,b$的公约数

因此$(a,b)$和$(b,a\bmod b)$的公约数是一样的,其最大公约数也必然相等,得证

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

递归到$(b==0)$,即上一次是$(a\%b=0)$,本次的$a$就是上一次的$b$

复杂度:设$a,b(a>b)$,$\gcd(a,b)=\gcd(b,a\bmod b)$,对$a$取模至少会让$a$折半,所以这一过程最多发生$O(\log n)$次

扩展欧几里得

扩欧在计算$\gcd(a,b)$的同时,也将$ax+by=\gcd(a,b)$的一组解$x,y$求出(其中可能有负数)

$ax_1+by_1=\gcd(a,b)$

$bx_2+(a\bmod b)y_2=\gcd(b,a\bmod b)$

因为$\gcd(a,b)=\gcd(b,a\bmod b)$

所以$ax_1+by_1=bx_2+(a\bmod b)y_2$

又因为$a\bmod b=a-(\left\lfloor\dfrac{a}{b}\right\rfloor\times b)$

所以$ax_1+by_1=bx_2+(a-(\left\lfloor\dfrac{a}{b}\right\rfloor\times b))\times y_2$

$ax_1+by_1=ay_2+bx_2-\lfloor\frac{a}{b}\rfloor\times by_2=ay_2+b(x_2-\lfloor\frac{a}{b}\rfloor y_2)$

因为$a=a$,$b=b$,所以$x_1=y_2$,$y_1=x_2-\left\lfloor\dfrac{a}{b}\right\rfloor y_2$

递归求解

当$b=0$时,$\gcd(a,b)=a$,此时$x=1$,$y=0$

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

 exgcd解不定方程

对于$ax+by=c$的不定方程,设$g=\gcd(a,b)$

当$c\%g!=0$时无整数解

当$c\%g=0$时,将方程右边$*\frac{g}{c}$转换成$ax+by=g$的形式

求得一组解$x_0$,$y_0$,再$*\frac{c}{g}$变回去

原方程解为$x_1=x_0*\frac{c}{g}$,$y_1=y_0*\frac{c}{g}$

通解为$x=x_1+\frac{b}{g}*t$,$y=y_1-\frac{a}{g}*t$,其中$t\in Z$

(这里$\frac{b}{g}$和$\frac{a}{g}$是最小的系数,所以求得的解是最全面的)

最小整数解:$x=(x\%b+b)%b$

注意$\gcd$只对非负整数有意义,若$a<0$则需预处理

posted @ 2021-02-07 11:59  FL4K  阅读(39)  评论(1编辑  收藏  举报
5 6