个人理解---扩展欧几里德定理
欧几里德定理:gcd(a,b)=gcd(b,a mod b)
gcd函数的基本性质:
gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)
定理:对于不完全为 0 的整数 a,b,gcd(a,b)表示 a,b 的最大公约数。
那么一定存在整数x,y使得gcd(a,b)= ax +by。而扩展欧几里德算法就是解决已知 a 和 b 求解 x 和 y 的算法;
ax1 + by1 = gcd(a, b)
bx2 + a%by2 = gcd(b, a%b)
因为 gcd(a, b) = gcd(b, a%b),
所以 ax1 + by1 = bx2 + a%by2
= bx2 + (a - a/b * b)y2;
= bx2 + ay2 - a/b * by2;
ax1 + by1 = ay2 + b(x2 - a/b * y2);
因此 x1 = y2;
y1 = x2 - a/b * y2;
同样x2和y2也可通过以上过程实现找到答案,最终递归结束的条件就是b=0了,此时ax + by = gcd(a, 0) = a;所以x=1;(但是y为什么别人都说等于0我就不知道了,我感觉y可以是任意值);
递归回溯时的x和y相当于上面解释过程中的y2 和 x2;所以我们需要保留原来的x以便于更新下面的y;
LL ex_gcd(LL a, LL b, LL &x, LL &y)///返回值是a和b的最大公约数; { if(b==0) { x = 1; y = 0; return a; } LL c = ex_gcd(b, a%b, x, y); LL temp = x; ///回溯中的x相当于之前的x所以要保留; x = y; ///对应x1 = y2; y = temp - a/b*y; ///对应y1 = x2 - a/b * y1; return c; }
由于 x 和 y 的值并不是唯一的,而是一个集合,ax+by = gcd(a,b)也可以写成 ax+by+nab-nab = gcd(a, b)(n=0,1,2,3...) 即 a(x-nb)+b(y+na)=gcd(a, b);(n=0,1,2,3,4...) 所以x-nb,y+na是对应的答案,我们可以根据题目要求进行选取 n 的大小;