GCD && ExtendGCD

 

之前版本

 

 计算最大公约数和不定方程

•GCD相关性质

  性质1.$GCD(a,b)=GCD(-a,b)=GCD(a,-b)=GCD(\left | a \right |,\left | b \right |)$;

  性质2.$GCD(a,b) = GCD(a,a-b) = GCD(b,a-b)$;  

  性质2推广.$GCD(a,b,c) = GCD(a,b-a,c-b) => GCD(a_1,a_2,...,a_n) = GCD(a_1,a_2-a_1,...,a_n-a_{n-1})$;  

  性质3.$GCD(a,b) = GCD(b,a\%b)$;

  性质4.$GCD(fib_a,fib_b) = fib_{GCD(a,b)}$;($fib_i$: 斐波那契数列的第 i 项)

  性质5.$GCD(a,b)\cdot LCM(a,b) = a\times b$;

  性质6.设 $GCD(m,a) = 1$,则有 $GCD(m,ab) = GCD(m,b)$;

     这就是说 “求 m 与另一个数的最大公约数时,可以把另一个数中与 m 互素的因数去掉”

  性质7.设 $GCD(m,a) = 1$,那么若 m  |  ab,则 m | b;

     这就是说 “若一个数被 m 整除,则把这个数中与 m 互素的因数去掉后仍被 m 整除”。

与GCD相关的习题

  [1]:CodeForces1152C , (my solution)

  [2]:POJ2773

•不定方程

  Bezout定理.如果 a,b 都是整数,则 ∃x,y 使得 ax+by = GCD(a,b);

  Bezout定理推广.如果 a,b 都是整数,且 GCD(a,b) | c,则 ∃x,y 使得 ax+by = c;

•利用拓展欧几里得算法求解不定方程

  $\begin{aligned} ax_1+by_1 &= GCD(a,b) \\ &= GCD(b,a\%b) \\ &=bx_2+a\%b\cdot y_2 \\ &= bx_2+(a-\lfloor \frac{a}{b} \rfloor \cdot b)y_2 \\ &=ay_2+b(x_2-\lfloor \frac{a}{b} \rfloor \cdot y_2)\end{aligned}$

  由此可知,x1,y1 基于 x2,y2

  一直执行欧几里得算法来到最后一步 $GCD(a_i,0) = a_i$; 

  即 $a_i x_i+0=a_i$

  所以,此时,满足此式的一个解为 xi=1,yi=0;

  然后,根据上述推导的式子,向前回溯,依次求出 (xi-1,yi-1),(xi-2,yi-2),...,(x1,y1);

•extendGCD求解ax+by=GCD(a,b)代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define GCD(a,b) __gcd(a,b)
 4 #define ll long long
 5 
 6 ///求解满足 ax+by=GCD(a,b) 的一组整数解(x,y)
 7 void extGCD(ll a,ll b,ll &x,ll &y)
 8 {
 9     if(b == 0)
10     {
11         x=1;
12         y=0;
13         return ;
14     }
15 
16     extGCD(b,a%b,y,x);
17     y -= (a/b)*x;
18 }
19 
20 int main()
21 {
22     ll a,b;
23     while(cin>>a>>b)
24     {
25         ll x,y;
26         extGCD(a,b,x,y);
27 
28         printf("满足%lldx+%lldy=%lld的一组整数解为(%lld,%lld)\n",a,b,GCD(a,b),x,y);
29     }
30 }

•extendGCD求解ax+by=c代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define GCD(a,b) __gcd(a,b)
 4 #define ll long long
 5 
 6 ///求解满足 ax+by=c 的一组整数解(x,y)
 7 void extGCD(ll a,ll b,ll &x,ll &y,ll c)
 8 {
 9     if(b == 0)
10     {
11         ///因为x=1求解的是ax+by=GCD(a,b)的解
12         ///所以要求解 ax+by=c 的解,只需在之前的基础上让x,y分别乘以c/GCD(a,b)即可
13         ///x=1*(c/a)=c/a
14         ///y=0*(c/a)=0
15         x=c/a;
16         y=0;
17         return ;
18     }
19 
20     extGCD(b,a%b,y,x,c);
21     y -= (a/b)*x;
22 }
23 
24 int main()
25 {
26     ll a,b,c;
27     while(cin>>a>>b>>c)
28     {
29         if(c%GCD(a,b) != 0)
30         {
31             puts("无解");
32             continue;
33         }
34 
35         ll x,y;
36         extGCD(a,b,x,y,c);
37 
38         printf("满足%lldx+%lldy=%lld的一组整数解为(%lld,%lld)\n",a,b,c,x,y);
39     }
40 }

•ax+by=GCD(a,b)的所有整数解(x,y)的求法

  通过拓展欧几里得求出 ax+by=GCD(a,b) 的一组解(x,y);

  那么,其所有解为:

  $\begin{aligned} &X=x+k\cdot \frac{b}{GCD(a,b)} \\ & Y=y-k\cdot \frac{a}{GCD(a,b)}\end{aligned}$

  其中 $k\in Z$;

与extendGCD相关的习题

  [1]:CodeForces1055C

  [2]:CodeForces548C

$GCD(fib_a,fib_b) = fib_{GCD(a,b)}$

posted @ 2019-07-23 16:57  HHHyacinth  阅读(322)  评论(0编辑  收藏  举报