中国剩余定理CRT —— JAVA实现

CRT描述

JAVA代码

/*中国剩余定理,根据公式需要求取大数的逆元*/
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;

public class CRT {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int n;
        BigInteger M_All = BigInteger.ONE,res = BigInteger.ZERO;
        ArrayList<BigInteger> b = new ArrayList<BigInteger>();
        ArrayList<BigInteger> m = new ArrayList<BigInteger>();
        ArrayList<BigInteger> M = new ArrayList<BigInteger>();
        ArrayList<BigInteger> Mi = new ArrayList<BigInteger>();                // M·Mi = 1 (mod mi)
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        for (int i = 0 ; i < n ; i++){
            b.add(scan.nextBigInteger());
            m.add(scan.nextBigInteger());
        }
        for (int i = 0 ; i < n ; i++){
            M_All = M_All.multiply(m.get(i));
        }
        for (int i = 0 ; i < n ; i++){
            BigInteger M_tmp = M_All.divide(m.get(i));
            M.add(M_tmp);
            Mi.add(getMi(M_tmp,m.get(i)));
        }
        for (int i = 0 ; i < n ; i++){
            res = res.add(M.get(i).multiply(Mi.get(i)).multiply(b.get(i)));
        }
        res = res.mod(M_All);
    }
    
    //获取Mi'使得满足MiMi' = 1 (mod m),使用扩展欧几里得算法
    public static BigInteger getMi(BigInteger M, BigInteger m){
        ArrayList<BigInteger> List_Q = new ArrayList<BigInteger>();
        ArrayList<BigInteger> List_S = new ArrayList<BigInteger>();
        BigInteger temp, res,m_rec = m;
        //通过辗转相除获得List_Q
        while (!m.equals(BigInteger.ZERO)){
            temp = m;
            List_Q.add(M.divide(m));
            m = M.remainder(m);
            M = temp;
        }
                
        //根据递推公式获得List_S
        List_S.add(BigInteger.ONE);
        List_S.add(BigInteger.ZERO);
        for (int i = 2 ; i < 1 + List_Q.size() ; i++){
            List_S.add(List_S.get(i - 2).subtract(List_Q.get(i - 2).multiply(List_S.get(i - 1))));
        }
        res = List_S.get(List_S.size() - 1);
        while (res.compareTo(BigInteger.ZERO) < 0){
            res = res.add(m_rec);
        }
        return res.mod(m_rec);
    }
}

 

转载于:https://www.cnblogs.com/nipo/p/7805797.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值