欧几里得算法
又称辗转相除法
迭代求两数 gcd 的做法
由 (a,b) = (a,ka+b) 的性质:gcd(a,b) = gcd(b,a mod b)
1 int gcd(int a,int b){ 2 if(b==0) return a; 3 return gcd(b,a%b); 4 }
O(logn)
裴蜀定理:
设 (a,b) = d,则对任意整数 x,y,有 d|(ax+by) 成立;
特别地,一定存在 x,y 满足 ax+by = d
等价的表述:不定方程 ax+by = c(a,b,c 为整数) 有解的充要条件为 (a,b)|c
推论:a,b 互质等价于 ax+by = 1 有解
扩展欧几里德算法
考虑如何求得 ax+by = d 的一个解。
这里 d = (a,b)
考虑使用欧几里德算法的思想,
令 a = bq+r,其中 r = a%b;
设求出 bx+ry = d 的一个解为 x = x0,y = y0,
我们可以知道gcd(a,b)最后一定会变成gcd(d,0)
所以ax + by = d => dx0 + 0y0 = d
所以x0 = 1,y0 = 任何数;
考虑如何把它变形成 ax + by = d 的解。
将 a = bq+r 代入 ax + by = d,
化简得 b(xq+y) +rx = d
我们令 xq+y = x0,x = y0,
则上式成立 故 x = y0,y = x0 −y0q 为 ax+by = d 的解
边界情况:b = 0 时,令 x = 1,y = 0 //不知道为啥y=0;qwq
1 void exgcd(int a,int b,int &x,int &y){ 2 if(b==0){ 3 x=1,y=0; 4 return; 5 } 6 int q=a/b,r=a%b; 7 exgcd(b,r,y,x); 8 y-=q*x; 9 }
先用 exgcd 求出任意一个解 x = x0,y = y0
再求出 ax+by = 0 的最小的解 x = dx = b/(a,b),y = dy = −a/(a,b)
所有解就是 x = x0 +kdx,y = y0 +kdy,
k 取任意整数