目录
拓展中国剩余定理(exCRT)
给定 \(n\) 组整数 \(a_i,b_i\) 求解非负最小/某区间内的整数 \(x\) 使得
\(\begin{cases} x\equiv a_1(\mod b_1) \\\ \\ x\equiv a_2(\mod b_2) \\\ \\ x\equiv a_3(\mod b_3) \\\ \\ ...... \\\ \\ x\equiv a_n(\mod b_n) \end{cases}\)
数据保证有解
我们先考虑一个子问题:
如果已知 \(\begin{cases} x\equiv a_1(\mod b_1) \\\ \\ x\equiv a_2(\mod b_2) \end{cases}\) 那怎么表示所有满足条件的整数 \(x\) 呢?
由第一个方程可知: \(x=a_1+t\cdot b_1,t\in Z\)
因此,我们代入第二个方程:
\(a_1+t\cdot b_1\equiv a_2(\mod b_2)\)
显然得到:
\(t\cdot b_1\equiv a_2-a_1(\mod b_2)\)
由拓展欧几里得算法(exGCD)可以求解 \(tb_1+mb_2=a_2-a_1\) 的 \(t,m\)
因此,保证有解的情况下, \(t\) 一定是可求的
最后我们求出 \(x=a_1+t\cdot b_1\) 是其中的一个解
而对于其余解 \(x'=a+t\cdot b_1+k\cdot lcm(b_1,b_2),k\in Z\) 显然也是符合上述的解
即归纳起来:
\(x\equiv a_1+t\cdot b_1(\mod lcm(b_1,b_2)\ )\)
回归正题,如果两个同余方程组可以如上求解,则 \(n\) 个方程的方程组显然可以:先用上述方法将 1.2 合并,变成 \((n-1)\) 个方程组;再将剩下的 1.2 合并,变成 \((n-2)\) 个方程组;以此类推,最后可以合并为一个方程组:
\(\displaystyle x\equiv a(\mod \text{lcm}_{i=1}^n b_i)\)
当然,对于原方程组,我们加入 \(x\equiv 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