您的位置:首页 > 其它

拓展欧几里德算法

2017-12-13 13:21 141 查看

拓展欧几里德算法

定义

已知整数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 ×<
4000
span style="border-left: 0.003em solid; display: inline-block; overflow: hidden; width: 0px; height: 0.737em; vertical-align: -0.063em;"> (-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)=(4730117)(10)(10)=(−73011−47)(4730)

或者用[[初等变换]]

⎛⎝⎜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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数论 ACM