中国剩余定理
定理
求解算法
-
令 m = ∏ i = 1 k m i , M i = m / m i ( i = 1 , 2 , … , k ) m = \prod_{i=1}^{k} m_{i},M_{i}=m/m_{i}(i=1,2,\ldots,k) m=∏i=1kmi,Mi=m/mi(i=1,2,…,k)
-
求 M i − 1 , 其 中 M i ∙ M i − 1 ≡ ( m o d m i ) M^{-1}_{i},其中M_{i}\bullet M_{i}^{-1}\equiv(mod \quad m_{i}) Mi−1,其中Mi∙Mi−1≡(modmi)
-
求 x ≡ ∑ i = 1 k M i ∙ M i − 1 ∙ b i ( m o d m ) x \equiv \sum_{i=1}^{k}M_{i} \bullet M_{i}^{-1} \bullet b_{i}(mod \quad m) x≡∑i=1kMi∙Mi−1∙bi(modm)
代码实现
import java.util.LinkedList;
import java.util.List;
public class CRT {
private List<Integer> mList;
private List<Integer> aList;
private long res = 0;
long m = 1;
long gcd(long a, long b) {
long r = 0;
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
private long getInverse(long a, long b) {
if (gcd(a, b) != 1) {
System.out.println("a,b不互素,无法求解逆元");
return 0;
}
long R1 = a, S1 = 1, T1 = 0;
long R2 = b, S2 = 0, T2 = 1;
long 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;
}
return (S1 + b) % b;
}
public CRT(List<Integer> aList, List<Integer> mList) {
this.mList = mList;
this.aList = aList;
if (this.mList.size() != this.aList.size()) {
System.out.println("m,a 不匹配");
this.mList = null;
this.aList = null;
}
}
public void compute() {
long[] Mi = new long[mList.size()];//M{i}
long[] Mi_inverse = new long[mList.size()];//M{i}_inverse
for (Integer integer : mList) {
m *= integer;
}
for (int i = 0; i < mList.size(); i++) {
Mi[i] = m / mList.get(i);
}
for (int i = 0; i < Mi.length; i++) {
Mi_inverse[i] = getInverse(Mi[i], mList.get(i));
}
for (int i = 0; i < aList.size(); i++) {
res += aList.get(i) * Mi[i] * Mi_inverse[i];
}
res = res % m;
}
public void printRes() {
System.out.println("---------------------------------------");
for (int i = 0; i < this.aList.size(); i++) {
System.out.printf("X ≡%4d" + " (mod %2d)\n", this.aList.get(i), this.mList.get(i));
}
System.out.println("---------------------------------------");
System.out.println("Result: \nX ≡ " + this.res + " (mod " + this.m + ")");
}
public static void main(String[] args) {
List<Integer> aList = new LinkedList<>();
aList.add(2);
aList.add(3);
aList.add(2);
List<Integer> mList = new LinkedList<>();
mList.add(3);
mList.add(5);
mList.add(7);
CRT crt = new CRT(aList, mList);
crt.compute();
crt.printRes();
}
}