#算法整理 扩展欧几里得

复习一下扩展欧几里得

扩展欧几里得是什么

即解方程

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

思路

首先确定的是要用递归求解,所以第一步要确定递归边界。类似欧几里得算法,我们先找到当\(b = 0\)的时候,有\(x = 1\),\(y = 0\)

\(y\)为什么等于\(0\)呢?因为当\(b = 0\)时,\(gcd(a,b) = gcd(a,0) = a\),而又有\(by = 0 \times y = 0\)所以\(y\)取啥都行,就在这里直接赋值0就好了

接下来考虑转移。

假设\(bx' + (a \% b)y' = gcd(a,b)\)有解,则

\[a\ \% \ b=a-\lfloor \frac ab\rfloor \\ bx′+(a-\lfloor \frac {a}{b}\rfloor)y′ = gcd(a,b) \]

整理得

\[ay'+b(x'-\lfloor \frac{a}{b} \rfloor*y')=gcd(a,b) \]

那么我们每次转移的时候就可以解这个方程

\[x = y' \\ y = x'-\lfloor \frac{a}{b} \rfloor*y' \]

就是说我们先递归到\(b = 0\)的时候,再依次往回更新\(x\)\(y\)的值。

代码

int exgcd(int a,int b,int &x,int &y){//这里用了取址符,这样就可以保存上一次的结果
    if(b == 0){
        x = 1;
        y = 0;
        return a;//返回他们的最大公因数
    }
    int r = exgcd(b,a % b,x,y);
    int temp = y;
    y = a - (a/b) * y
    x = temp;
    return r;//lcez_cyc
}

例题

luogu P1082 同余方程

求关于方程\(ax \equiv 1 (\mod b)\)的最小整数解

答题过程:

\[ax = yb + 1 \\ ax - by = 1 \\ \because gcd(a,b) = 1 \\ \therefore ax + by = gcd(a,b) \]

为什么从减变成加了呢?因为\(y\)是我们随意设的数字,\(y\)可正可负,但是\(a,b\)是不能小于零的

posted @ 2020-01-28 21:53  CYC的幸福生活  阅读(148)  评论(0编辑  收藏  举报