在看扩展欧几里得之前需要了解下欧几里得算法
扩展欧几里得是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d
功能:求出a , b的最大公约数,且求出x,y满足ax + by = gcd(a,b)
/*
*复杂度o(logN), 其中N与a,b同阶
*输入:a,b 两个整数
* &x,&y 引用,ax+by=gcd(a,b)的一组解
*输出:a和b的最大公约数
*调用后x,y满足方程ax+by=gcd(a,b)
*/
int extend_gcd(int a,int b,int &x,int &y){
if (b==0){
x=1,y=0;
return a;
}
int r=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return r;
}
当 b = 0是,有x = 1,y = 0时等式成立。
当b > 0时,在欧几里得算法的基础上,已知
gcd(a,b) = gcd(b,a mod b)
先递归求出x' , y' 满足:
bx' + (a mod b)y' = gcd(b , a mod b) = gcd(a , b)
然后回推,将上式化简得:
bx' + (a - a/b*b)y' = gcd(a , b)
a - a/b*b即为mod运算 , a/b 代表取小于a/b的最大整数。
ay' + bx' - (a / b)*by' = gcd(a , b);
提取因式b,得:
ay' + b(x' - a/b*y') = gcd(a,b)
故 x = y', y = x' - a/b*y'。
我们就得到了求解 x,y 的方法:x',y' 的值基于 x',y'.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
扩展欧几里得还可以用来求乘法逆元