拓展欧几里德算法
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; } }
相关文章推荐
- 同余方程(拓展欧几里德算法)
- 欧几里德算法及拓展
- Sicily1099-Packing Passengers-拓展欧几里德算法
- 通过POJ1061青蛙的约会来谈拓展欧几里德算法
- POJ 1061青蛙的约会(拓展欧几里德算法)
- 拓展欧几里德算法
- POJ 1064 青蛙的约会(拓展欧几里德算法)
- 证明拓展欧几里德算法
- 欧几里德 和 拓展欧几里德算法
- 对于拓展欧几里德算法的理解
- 如何使用循环而不是递归反推的方式实现拓展欧几里德算法
- 欧几里德与拓展欧几里德算法
- 欧几里德算法及拓展
- 拓展欧几里德算法求逆元2
- UVA 12196 Disgruntled Judge 拓展欧几里德算法
- POJ 1061 拓展欧几里德算法
- 欧几里德算法和拓展欧几里德算法
- 欧几里德算法及其拓展算法
- 拓展欧几里德算法
- POJ 2115 C Looooops (拓展的欧几里得) 拓展的欧几里得详解