扩展欧几里得

  1. 原理:
    已知a, b,求解一组x,y,使它们满足不等式: ax+by =gcd(a, b)

    假设 a>b,

    (1)  b=0  gcd(a,b) = a ,  ax = a ,  则x=1,y=0;

    (2) 假设 ax1+by1=gcd(a,b) (方程一) bx2+(a%b)y2=gcd(b,a%b)(方程二);由欧几里得算法gcd(a,b) =gcd(b,a%b) 得到,

    ax1+by1 = bx2+(a%b)y2,即ax1+by1=bx2+(a-a/b*b)y2 ax1+by1=ay2+b(x2-a/b*y2)

    在根据多项式恒等定理(把a,b看成变量),x1=y2; y1=x2-a/b*y2;

    由于需要有 x2,y2 求得 x1,y1 因此容易想到使用递归求解,出口条件就是 (1)条件

  2. 代码:
 1 void extend_gcd(ll a, ll b, ll &gcd, ll &x, ll &y) {
 2     if (b == 0) {
 3         gcd = a;
 4         x = 1;
 5         y = 0;
 6     } else {
 7         extend_gcd(b, a % b, gcd, x, y);
 8         int x2 = x, y2 = y;
 9         x = y2;
10         y = x2 - (a / b) * y2;
11     }
12 }
13 
14 //ax + by = gcd(a,b)
15 //gcd 保存了 a,b 的最大公约数
16 void ext_gcd(ll a, ll b, ll &gcd, ll &x, ll &y) {
17     if (!b) { gcd=a; x=1; y=0; }
18     else { ext_gcd(b,a%b,gcd,y,x); y-=(a/b)*x; }
19     // 理解上面这个这句话就用上面的 extend_gcd 来理解,主要是使用了引用的概念
20     // 并且 ext_gcd 在 y-=(a/b)*x 上面,也就是说 ext_gcd 参数中的 x,y 都是
21     // 下一层函数返回的 x2, y2
22     // 然后使用 y-=(a/b)*x 处理一下本层函数 y1 即可
23 }

 

posted @ 2018-07-30 16:11  佰大于  阅读(171)  评论(0编辑  收藏  举报