#算法整理 扩展欧几里得
复习一下扩展欧几里得
扩展欧几里得是什么
即解方程
\[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\)是不能小于零的