扩展中国剩余定理[学习笔记]
很久以前就学了(crt)和(Excrt),但一直都没有真正理解。今天又重新学习了一下,尤其是推式子的过程,就整理一下吧
(Excrt)用来解决的问题:
求解关于a的同余方程组:
[egin{cases}
aequiv b_1 (mod c_1)\
aequiv b_2 (mod c_2)\
...\
aequiv b_3 (mod c_n)\
end{cases}
]
不保证(ci,cj)互质
解法
已经知道了对于单一的关于(a)的同余方程(a=b_i (mod) (c _i)),可以用exgcd的方法去求,那么只要我们将方程组的各个方程合成一个方程不就可以求解了吗?
将两个同余方程
[egin{cases}
aequiv b_i (mod c_i)\
aequiv b_j (mod c_j)\
end{cases}
]
合并 :
联立方程组得
[a=x_ic_i+b_i=x_jc_j+b_j
]
两边交换
[x_ic_i-x_jc_j=b_j-b_i
]
[x_ic_iequiv b_j-b_i(mod c_j)
]
设(c,d)为
[c=b_j-b_i,d=gcd(c_i,c_j)
]
很明显如果不满足(d|c),方程无解
同除d,得
[frac{c_i}{d}x_iequiv frac{c}{d}(mod frac{cj}{d})
]
[x_iequiv frac{c}{d}*inv(frac{c_i}{d})(mod frac{cj}{d})
]
设(K=frac{c}{d}*inv(frac{c_i}{d})),则
[x_i=K+yfrac{c_j}{d}
]
将(x_i)代回原来的(a=x_ic_i+b_i),得
[a=Kc_i+yfrac{c_ic_j}{d}+b_i
]
[aequiv Kc_i+b_i(mod frac{c_ic_j}{d})
]
合并完成,新的(b_i=Kc_i+b_i,c_i=frac{c_ic_j}{d})
代码(照着上面膜你就好啦)
void excrt(ll bj,ll cj){
if(bi==0&&ci==0){
bi=bj,ci=cj;
return;
}
ll C=bj-bi,d=gcd(ci,cj),P=ci/d*cj;
if(C%d!=0){err=1; return;}
ll K=e(C/d%(cj/d),inv(ci/d,cj/d),(cj/d));
bi=(e(K,ci,P)+bi)%P,ci=P;
}