diff --git a/src/main/java/me/hatter/math/Crt.java b/src/main/java/me/hatter/math/Crt.java new file mode 100644 index 0000000..1df022d --- /dev/null +++ b/src/main/java/me/hatter/math/Crt.java @@ -0,0 +1,40 @@ +package me.hatter.math; + +import java.math.BigInteger; + +public class Crt { + + public static void main(String[] args) { + System.out.println(crt( + new BigInteger[]{ + BigInteger.valueOf(2), + BigInteger.valueOf(3), + BigInteger.valueOf(2), + }, + new BigInteger[]{ + BigInteger.valueOf(3), + BigInteger.valueOf(5), + BigInteger.valueOf(7), + } + )); + } + + // https://oi-wiki.org/math/number-theory/crt/ + public static BigInteger crt(BigInteger[] as, BigInteger[] ns) { + BigInteger n = BigInteger.ONE; + // \prod n_i + for (BigInteger ni : ns) { + n = n.multiply(ni); + } + BigInteger x = BigInteger.ZERO; + for (int i = 0; i < as.length; i++) { + // m_i = n / n_i + BigInteger mi = n.divide(ns[i]); + // c_i = m_i^-1 mod n_i + BigInteger miInv = mi.modInverse(ns[i]); + // \sum a_i m_i c_i mod n + x = x.add(as[i].multiply(mi.multiply(miInv))).mod(n); + } + return x.mod(n).add(n).mod(n); + } +}