exCRT 浅析

exCRT

处理 CRTai 不互质的情况。
一般使用 exCRT 毕竟其又好想又好写。

x=b1(moda1)x=b2(moda2)x=bn(modan)

exCRT 的核心在于维护一个同余方程,并将同余方程不断合并。

假设现在合并了前 i1 个方程,不妨设

ans=ans0+km,kZ

现在要 ans 同时满足两个方程

ans=ans0+kmans=bi+k1ai

两式相减有

kmk1ai=bians0

这是一个同余方程,假设其解为
k=y+jp,jZ
回代 ans=ans0+(y+jp)m=(ans0+ym)+jpm
ans0=ans0+ym,m=mp,ans=ans0+km
发现又回到了原来的形式,合并完成。

这个解系满足 ans=(ans0+ym)+jpm=ans0(modm)
同时也满足第 i 个方程 ans=ans0+km=bi+k1ai

接下来证明这样不会漏解


引理 : 两个同余方程在 lcm(a1,a2) 内有唯一解。
证明 : 反证法。
假设存在两个不同的解 0x,y<lcm(a1,a2)
不妨设 x>y

(xy)=0(moda1)(xy)=0(moda2)

换句话说

a1(xy)a2(xy)

则有

lcm(a1,a2)(xy)

由于 xy<lcm(a1,a2)
所以 xy=0,x=y 不符题意。

证毕。


考虑 m=pm

p=aigcd(m,ai)m=pm=aigcd(m,ai)m=maigcd(m,ai)=lcm(m,ai)

因此不会漏解。

在写代码时,直接取 m=lcm(m,ai) 即可。

P4777 【模板】扩展中国剩余定理(EXCRT)
Code:

copy
typedef 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; }

关于标准形式和一般形式的转化。

x=bi(modai) 是标准形式。
cix=bi(modai) 是一般形式。

一般形式不可直接求解,得先 标准。

考虑先分别求解每一个 cix=bi(modai) ,由于 gcd(ci,ai) 不一定为 1 ,所以 ci 不一定移得过去。

直接求解 cix+aik=bi,注意 x 的解集可以写成

x=x0(modaigcd(ai,ci))

这是标准形式,对新的方程组求解即可。

若单个方程都没有解,那么总的也没有解。

posted @   cjlworld  阅读(298)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起