细节

对于扩展欧几里得算法中x,y的位置关系有无数种模板,可以交换位置,也可以不交换位置,甚至可以加减常数
y总给的模板

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

为什么这样写正确:
首先对于我这个函数exgcd(a,b,x,y)应该等于上一步exgcd(a, a%b, y, x) 其中写出来是
$a * x + b * y = d$ 本步骤
$a * y + (a % b) * x = d$ 上一步
所以应该是本步骤等于上一步通过对比系数得到
$x = x$
$y = y - a / b * x;$
除了y总给出的模板还可以写成这样

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;
}

或者这样(只是比较麻烦罢了)

int exgcd(int a, int b, int &x, int &y){
    if(!b){
        x = 1 , y = 0;
        return a;
    }
    int t1,t2;
    int d = exgcd(b, a%b, t1, t2);
    x = t2 , y = t1 - a / b * t2; //其实跟x, y 本身没有什么关系,只跟x, y与t1, t2的关系有关
    return d;
}

甚至在if语句中的y = 0 这个也可以改变,不一定非要是零,因为y可以是任意常数
如这样:

int exgcd(int a, int b, int &x, int &y){
    if(!b){
        x = 1 , y = 6666;//y 可以等于任意常数
        return a;
    }
    int d = exgcd(b, a%b, x, y);
    int t = x;
    x = y ;
    y = t - a/b * y;
    return d;
}

但是引用传递的过程貌似不能加减,但是符合数学的逻辑,不通过引用应该是可以实现的。区别就是结果可能不一样,但一定是一个解