拓展欧几里得算法
原理
根据广义欧几里得算法知道,GCD(a,b)是如何求出a,b两者的最大公因数的。可以将下式看作递推式
r
−
2
,
.
.
,
r
n
−
1
r_{-2},..,r_{n-1}
r−2,..,rn−1
如果将
r
n
−
1
,
r
n
−
2
,
.
.
.
,
r
2
,
r
1
,
r
0
r_{n-1},r_{n-2},...,r_{2},r_{1},r_{0}
rn−1,rn−2,...,r2,r1,r0
逐项回带,则可以得到整数s,t使得
s
a
+
t
b
=
(
a
,
b
)
sa+tb=(a,b)
sa+tb=(a,b)
其实这就是贝祖等式
贝祖等式
例题
首先
再逐项带回
算法实现
原理
证明
HashMap<String, Integer> extendedEuclid(int a, int b) {
int R1 = a, S1 = 1, T1 = 0;
int R2 = b, S2 = 0, T2 = 1;
int q = 0, temp1, temp2, temp3;
while (R2 != 0) {
q = R1 / R2;//向下取整
temp1 = R1 - q * R2;
temp2 = S1 - q * S2;
temp3 = T1 - q * T2;
R1 = R2;
S1 = S2;
T1 = T2;
R2 = temp1;
S2 = temp2;
T2 = temp3;
}
//结果集 R是最大公因数,S是a的系数,T是b的系数
HashMap<String, Integer> res = new LinkedHashMap<>();
res.put("R", R1);
res.put("S", S1);
res.put("T", T1);
return res;
}
意义
为什么要找S,T使得
S
a
+
T
b
=
(
a
,
b
)
Sa+Tb=(a,b)
Sa+Tb=(a,b)
主要是用于找逆元
当(a,b)=1时,
a
x
≡
1
(
m
o
d
b
)
ax \equiv 1 (mod \quad b)
ax≡1(modb)
易知
x
≡
a
−
1
(
m
o
d
b
)
x \equiv a^{-1}(mod \quad b)
x≡a−1(modb)
其中
a
−
1
a^{-1}
a−1
就是逆元,
也就是上式的 S
当S为负数时通过以下方式求解,
(
b
+
s
)
%
b
(b+s) \% b
(b+s)%b
例如
3
x
≡
1
(
m
o
d
4
)
3x \equiv 1 (mod \quad 4)
3x≡1(mod4)
得
R:1
S:-1
T:1
其中S为负,则
(-1 + 4) % 4 = 3
故3是3(mod 4)的逆元,事实上 3*3 = 9 , 9 % 4 = 1
求逆元的方法
int inverse(int a, int b) {
HashMap<String, Integer> res = extendedEuclid(a, b);
if (res.get("R") != 1)
return 0;//不是逆元
else
return (b + res.get("S")) % b;
}