也叫”孙子定理”
例题
给定 2n 个整数 a1,a2,…,an 和 m1,m2,…,mn,求一个最小的非负整数 x,满足 ∀i∈[1,n],x≡mi(mod ai)。
输入格式
第 1 行包含整数 n。
第 2…n+1行:每 i+1行包含两个整数 ai 和 mi,数之间用空格隔开。
输出格式
输出最小非负整数 x,如果 x 不存在,则输出 −1。
如果存在 x,则数据保证 x 一定在 64 位整数范围内。
数据范围
1≤ai≤231−1
0≤mi
输入样例:
28 711 9
输出样例:
31
思路:
不是严格意思上的中国剩余定理,因为题目没有说任意 mi, mj 两两互质
所以可能有解,也可能无解,需要一步一步算
每次合并两个同余式并判断是否有解,有解则继续计算,否则退出计算
表达整式的奇怪方式.pdf
import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();long a1, m1;a1 = sc.nextLong();m1 = sc.nextLong();//解的标识boolean flag = true;long x = 0;for (int i = 0; i < n - 1; i++) {long a2, m2;a2 = sc.nextInt();m2 = sc.nextInt();long[] k1 = new long[1], k2 = new long[1];long d = exgcd(a1, a2, k1, k2);//是否有解的判断if ((m2 - m1) % d != 0) {flag = false;x = -1;break;}//有解long t = (m2 - m1) / d;//求系数解k1[0] *= t;//求系数的最小非负整数特解k1[0] = (k1[0] % (a2/d) + (a2/d)) % (a2/d);//求当前x的特解x = k1[0] * a1 + m1;//求x的通解系数,方便下一轮迭代m1 = x;a1 = Math.abs(a1 / d * a2);}System.out.println(x);}static long exgcd(long a, long b, long[] x, long[] y) {if (b == 0) {x[0] = 1;y[0] = 0;return a;}long d = exgcd(b, a % b, y, x);y[0] -= a / b * x[0];return d;}}
