中国剩余定理:
- 一次同余方程组:
一次同余方程组是指形如 x≡aimodmi(i=1,2,…,k) 的同余方程构成的组
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧x≡a1modm1x≡a2modm2x≡a3modm3...x≡akmodmk
中国剩余定理的主要用途是解一次同余方程组,其中 m1,m2,...,mk 互质
- 中国剩余定理:
令 M=m1⋅m2⋅...⋅mk(即所有 m 的 lcm )
ti 为同余方程 miM⋅ti≡1modmi 的最小正整数解
则存在解 x=∑ai⋅miM⋅ti
通解为 x+i⋅M
最小非负整数解为 (x%M+M)%M
(我承认这段是抄的 orz )
原文看起来更方便:https://blog.csdn.net/niiick/article/details/80229217
miM⋅ti≡1modmi 可转化为 miM⋅ti+mi⋅y=1 ,然后用 exgcd 求 ti
其中 gcd(miM,mi)=1 意味着方程组一定有解
- 证明:
对于第 k 个方程
①当 i=k 时,有 mk∣miM ,即 ai⋅miM⋅ti≡0modmk
②当 i=k 时,有 mkM⋅tk≡1modmk ,即 ak⋅mkM⋅tk≡akmodmk
故 ∑ai⋅miM⋅ti≡akmodmk
- 代码:
(其中 LL 是 long long ,qcm 是快速乘)
1 2 3 4 5 6 7 8 9 10
| LL crt(){ LL bwl=0; for(int i=1;i<=k;++i){ LL x,y; exgcd(M/m[i],m[i],x,y); if(x<0) x=x%m[i]+m[i]; bwl=(bwl+qcm(qcm(a[i],M/m[i]),x))%M; } return (bwl+M)%M; }
|
- 孙子算经:
《孙子算经》:今有物不知其数,三三数之剩二;五五数之剩三;七七数之剩二。问物几何?
《算法统宗》:三人同行七十稀,五树梅花廿一枝,七子团圆月正半,除百零五便得知。
其中 70=7×5×2,70%3=1,21=3×7×1,21%5=1,15=3×5×1,15%7=1
用 70×2+21×3+15×2=233 除 3×5×7=105 ,得到的余数 23 即为答案
70=3×5×2,21=3×7×1,15=3×5×1 三式中的最后一个乘数 2,1,1 即为上文提到的 di
数字还挺吉利的 233
扩展中国剩余定理:
- 一次同余方程组:
扩展中国剩余定理的主要用途是解一次同余方程组,其中 m1,m2,...,mk 不一定互质
2.扩展中国剩余定理:
令前 k−1 个方程组成的同余方程组的一个解为 x
且 M 为前 k−1 个模数的 lcm
则前 k−1 个方程的方程组的通解为 x+i⋅M
现在将第 k 个方程加入
只需求一个正整数 t ,使得
x+t⋅M≡akmodmk
可以转化为 M⋅t+mk⋅y=ak−x
然后用 exgcd 求出 t
若此方程无解,则整个同余方程组无解
否则 x+t⋅M 为前 k 个方程的方程组的一个解
(这段也是我抄的,原文和上边一样 orz )
- 代码:
(其中 LL 是 long long ,qcm 是快速乘,三个参数分别为两个乘数和模数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| LL excrt(){ LL M=m[1],ans=a[1]; for(int i=2;i<=k;++i){ LL x,y; LL d=gcd(M,m[i]); LL c=(a[i]-ans%m[i]+m[i])%m[i]; if(c%d) return -1; exgcd(M,m[i],x,y); x=qcm(x,c/d,m[i]/d); ans+=qcm(x,M,M*m[i]); M*=m[i]/d; ans=(ans%M+M)%M; } return ans; }
|
- 细节:
1.有些题数字卡得严,必须要用快速乘
2.快速乘时注意第二个乘数必须为正,要用通解处理
3.每次快速乘的模数不一定一样,需要好好考虑
例题:
洛谷3868 猜数字
洛谷4777 扩展中国剩余定理