再将exgcd之前,我们还是回顾一下gcd吧。
gcd:求两个数的最大公因数 时间复杂度:O(logn)
常规代码:循环
int gcd(int a,int b){
while(b>0){
int y;
y=a%b;
a=b;
b=y;
}
return a;
}
gcd简化代码:递归 (递归更容易看出辗转相除法的运算过程)
int gcd(int a,int b){
if(b==0) return a;
else return gcd(b,a%b);
}
EXGCD:ax+by=gcd(a,b) 时间复杂度:O(logmax(a,b))
问题:主要计算这个方程的解(x,y)
证明过程:
设ax1+by1=gcd(a,b)
bx2+(a mod b)*y1=gcd(b,a mod b) -------> gcd(a,b)=gcd(b,a mod b)
ax1+by1=bx2+(a mod b)*y2
ax1+by1=bx2+(a -(a/b)*b)*y2
ax1+by1=ay2+b*(x2-(a/b)*y2)
x1=y2 y1=x2-(a/b)*y2
在式子的演变过程中,其实可以发现,x,y的最终系数,其实跟gcd(a,b)相关的,也就是说,通过exgcd,你可以很快的求出同余方程x,y的值以及系数的gcd。
(附:其实本人认为,各位读者并没有必要一定要弄懂这个证明过程,此算法本为应用型,只要记住这个exgcd的算法流程以及能够运用代码解题即可)
exgcd板子:
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
int xx,yy;
int d=exgcd(b,a%b,xx,yy);
x=yy;
y=xx-(a/b)*yy;
return d;
}
exgcd魔改简化版:
void exgcd(int a,int b,int &x,int &y){
if(b==0) {
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);//改变了原有x,y的位置
y-=(a/b)*x;
}
以上为exgcd的基础知识,感谢各位读者的阅读