中国剩余定理

中国剩余定理

定理

image-20211008222628196

求解算法

  1. 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)

  2. 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}) Mi1,MiMi1(modmi)

  3. 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) xi=1kMiMi1bi(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();
    }
}

image-20211009190714915

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

都学点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值