拓展中国剩余定理

目录

目录地址

上一篇

下一篇


拓展中国剩余定理(exCRT)

给定 (n) 组整数 (a_i,b_i) 求解非负最小/某区间内的整数 (x) 使得

(egin{cases} xequiv a_1(mod b_1) \ \ xequiv a_2(mod b_2) \ \ xequiv a_3(mod b_3) \ \ ...... \ \ xequiv a_n(mod b_n) end{cases})

数据保证有解


我们先考虑一个子问题:

如果已知 (egin{cases} xequiv a_1(mod b_1) \ \ xequiv a_2(mod b_2) end{cases}) 那怎么表示所有满足条件的整数 (x) 呢?

由第一个方程可知: (x=a_1+tcdot b_1,tin Z)

因此,我们代入第二个方程:

(a_1+tcdot b_1equiv a_2(mod b_2))

显然得到:

(tcdot b_1equiv a_2-a_1(mod b_2))

由拓展欧几里得算法(exGCD)可以求解 (tb_1+mb_2=a_2-a_1)(t,m)

因此,保证有解的情况下, (t) 一定是可求的

最后我们求出 (x=a_1+tcdot b_1) 是其中的一个解

而对于其余解 (x'=a+tcdot b_1+kcdot lcm(b_1,b_2),kin Z) 显然也是符合上述的解

即归纳起来:

(xequiv a_1+tcdot b_1(mod lcm(b_1,b_2) ))


回归正题,如果两个同余方程组可以如上求解,则 (n) 个方程的方程组显然可以:先用上述方法将 1.2 合并,变成 ((n-1)) 个方程组;再将剩下的 1.2 合并,变成 ((n-2)) 个方程组;以此类推,最后可以合并为一个方程组:

(displaystyle xequiv a(mod ext{lcm}_{i=1}^n b_i))

当然,对于原方程组,我们加入 (xequiv 0(mod 1)) 也是允许的,因此,我们可以用这个作为初始条件:

int exgcd(int a,int b,int &x,int &y){
    ...
}
void excrt(int &a1,int &b1,int a2,int b2){
    int t,m,g=exgcd(b1,b2,t,m);
    t*=a2-a1;
    a1=a1+t*b1;
    b1=b1/g*b2;
    a1=(a1%b1+b1)%b1;
}
...
int a=0,b=1;
for(int i=1;i<=n;i++){
    int tmpa=read(),tmpb=read();
    excrt(a,b,tmpa,tmpb);
}
原文地址:https://www.cnblogs.com/JustinRochester/p/12425171.html