exCRT 浅析
exCRT
处理 CRT 中 不互质的情况。
一般使用 exCRT 毕竟其又好想又好写。
exCRT 的核心在于维护一个同余方程,并将同余方程不断合并。
假设现在合并了前 个方程,不妨设
现在要 同时满足两个方程
两式相减有
这是一个同余方程,假设其解为
回代
故
发现又回到了原来的形式,合并完成。
这个解系满足
同时也满足第 个方程
接下来证明这样不会漏解
引理 : 两个同余方程在 内有唯一解。
证明 : 反证法。
假设存在两个不同的解
不妨设
则
换句话说
则有
由于
所以 不符题意。
证毕。
考虑
因此不会漏解。
在写代码时,直接取 即可。
P4777 【模板】扩展中国剩余定理(EXCRT)
Code:
copytypedef long long LL;
LL muler(LL x,LL k,LL MOD)
{
LL res=0; k=(k%MOD+MOD)%MOD; x=(x%MOD+MOD)%MOD;
while(k) {
if(k&1) res=(res+x)%MOD;
x=(x+x)%MOD; k>>=1;
}
return res%MOD;
}
LL exgcd(LL a,LL b,LL& x,LL& y)
{
if(b==0) {
x=1; y=0;
return a;
}
LL z=exgcd(b,a%b,y,x);
y-=a/b*x;
return z;
}
LL excrt(int n,LL b[],LL a[])
{
for(int i=1;i<=n;i++) b[i]%=a[i]; // 先把 b[i] mod a[i] 否则 n=1 会错。
LL m=a[1],ans=b[1]; // 维护方程的解系为 {ans} = ans0 + k*m
for(int i=2;i<=n;i++) { // 尝试把第 i 个方程加入解系。
LL y,z,d=exgcd(m,a[i],y,z);
if((b[i]-ans)%d!=0) return -1; // 无法合并同余方程 --> 没有合法解
y=muler(y,(b[i]-ans)/d,a[i]/d); // 同余方程的最小正整数解。
ans+=y*m;
m=m/d*a[i]; // m = lcm{a[1]...a[i]} , 不要通过同余方程,这样就很方便,注意先除后乘。
ans=(ans%m+m)%m; // 让 ans 为最小正整数。
}
return ans;
}
关于标准形式和一般形式的转化。
是标准形式。
是一般形式。
一般形式不可直接求解,得先 标准。
考虑先分别求解每一个 ,由于 不一定为 ,所以 不一定移得过去。
直接求解 ,注意 的解集可以写成
这是标准形式,对新的方程组求解即可。
若单个方程都没有解,那么总的也没有解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】