扩展中国剩余定理(Excrt)笔记

扩展中国剩余定理(excrt)

本来应该先学中国剩余定理的。但是有了扩展中国剩余定理,朴素的 CRT 就没用了。

扩展中国剩余定理用来求解如下形式的同余方程组:

{xa1 (mod b1)xa2 (mod b2)...xan (mod bn)

扩展中国剩余定理的基本思想是合并,通过 n1 次合并,将一个大的同余方程组合并成一个同余方程。

假设现在有两个同余方程:

{xa (mod A)xb (mod B)

现在要将他们合并。首先转化成不定方程:

{A|(xa)B|(xb)

{xa=Ak1xb=Bk2

{x=a+Ak1x=b+Bk2

a+Ak1=b+Bk2

Ak1Bk2=ba

成功转化成了系数为 (A,B,ba) 的不定方程,使用 exgcd 求出他的一个根。因此转化成了一个同余方程:xAk1+a(mod lcm(A,B))。合并完成。

// 合并 x = a(mod A), x = b(mod B) 两个方程
// 返回的是新的 a', b',满足 x = a'(mod b')
PII merge(int a, int A, int b, int B) {
	int k1, k2; int d = exgcd(k1, k2, A, B);
	k1 = k1 * (b - a) / d;
	int p = A / d * B; return {(A * k1 + a) % p, p};
}

bonus:

  1. 如果 x 的系数不为 1

也就是 P4774 [NOI2018] 屠龙勇士

求解形如:

{p1xa1 (mod b1)p2xa2 (mod b2)...pnxan (mod bn)

Excrt 因为 x 的系数是一,因此可以直接联立两个不定方程。也尝试将这个东西转化成不定方程的形式。假设现在需要合并的两个同余方程是:

{pxa(mod b)PxA(mod B)

{b|(pxa)B|(PxA)

{pxa=k1bPxA=k2B

{pxk1b=aPxk2B=A

然后发现两个 x 的系数不同,不能直接合并了。而这两个柿子两边又不能同时除以 p 或者 P,因为不保证逆元存在。这就非常难搞。

一个神奇的思路是直接解出两个方程。以第一个方程为例,方程中只有两个未知数 xk1,可以解出一个特解 x0。那么所有 x 就可以表示成:

x=x0+b(p,b)×α

同理解第二个方程,可以得到

x=x1+B(P,B)×β

我们惊奇的发现这两个 x 的系数相同了。所以可以合并一下:

x0+b(p,b)×α=x1+B(P,B)×β

里面只有 α,β 两个未知数,解出他们两个就可以得到 x

  1. 扩展中国定理进行模数非质数的合并

古代猪文

(nm)mod 999911658 的值。

999911658 质因数分解得到:999911658=2×3×4679×35617

因此可以对 2,3,4679,35617 分别做一遍 Lucas,得到下面的同余方程:

{xa1(mod 2)xa2(mod 3)xa3(mod 4679)xa4(mod 35617)

可以直接用 excrt 合并一下。

另外一个应用是扩展卢卡斯。其基本思路也是将模数拆成若干质因数的次方,计算后 excrt 合并。

posted @   Link-Cut-Y  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示