拓展欧几里德算法
定义
已知整数a,b,必存在整数x,y,使得
ax + by = gcd(a,b).
例子
用类似辗转相除法,求二元一次不定方程 47x+30y=1的整数解。
- 47 = 30 × 1 + 17
- 30 = 17 × 1 + 13
- 17 = 13 × 1 + 4
- 13 = 4 × 3 + 1
然后把它们改写成“余数等于”的形式
- 17 = 47 × 1 + 30 × (-1) //式1
- 13 = 30 × 1 + 17 × (-1) //式2
- 4 = 17 × 1 + 13 × (-1) //式3
- 1 = 13 × 1 + 4 × (-3)
然后把它们“倒回去”
- 1 = 13 × 1 + 4 × (-3)
- 1 = 13 ×1 + [17 × 1 + 13 × (-1)] * (-3) //应用式3
- 1 = 17 × (-3) + 13 × 4
- 1 = 17 × (-3) + [30 × 1 + 17 × (-1)] × 4 //应用式2
- 1 = 30 × 4 + 17 × (-7)
- 1 = 30 × 4 + [47 × 1 + 30 × (-1)] × (-7) //应用式1
- 1 = 47
×
(-7) + 30
×
11
得解 x=-7, y=11 。
这个过程可以用矩阵表示(其中q表示商,r表示余数)
(a b)=∏Ni=0(qi110)(rN−10)
(47 30)=(1110)(1110)(1110)(3110)(4110)(10)=
或者用[[初等变换]]
⎛⎝⎜47103001⎞⎠⎟→⎛⎝⎜171−13001⎞⎠⎟→⎛⎝⎜171−113−12⎞⎠⎟
→⎛⎝⎜42−313−12⎞⎠⎟→⎛⎝⎜42−31−711⎞⎠⎟⇒1=47(−7)+30(11)
代码
int gcdEx(int a, int b, int *x, int *y)
{
if(b==0)
{
*x = 1,*y = 0;
return a;
}
else
{
int r = gcdEx(b, a%b, x, y); /* r = GCD(a, b) = GCD(b, a%b) */
int t = *x;
*x = *y;
*y = t - a/b * *y;
return r;
}
}