Always ke|

kroyosh

园龄:3年7个月粉丝:1关注:1

拓展中国剩余定理 exCRT

求解如下形式的一元线性同余方程组(其中 n1,n2,···,nk 两两互质)

{xa1(mod n1)xa2(mod n2)xak(mod nk)

  • 推导:从简单入手,先考虑同于方程组只有两个式子的情况

xc1 (mod m1)

xc2 (mod m2)

变形:

x=c1+m1k1

x=c2+m2k2

联立:

c1+m1k1=c2+m2k2

移项:

m1k1=c2c1+m2k2

(a,b) 表示 ab 的最大公约数。
方程有解的条件为 (m1,m2)|(c2c1).
对于上面的方程,两边同除 (m1,m2)

m1k1(m1,m2)=(c2c1)(m1,m2)+m2k2(m1,m2)

转换:

m1(m1,m2)k1c2c1(m1,m2)(mod m2(m1,m2))

同余式两边同除 m1(m1,m2)

k1inv(m1(m1,m2),m2(m1,m2))×(c2c1)(m1,m2)(mod m2(m1,m2))

k1=inv(m1(m1,m2),m2(m1,m2))×(c2c1)(m1,m2)+m2(m1,m2)×y

inv(a,b) 表示 a 在模 b 意义下的逆元。
k1 代入 x=c1+m1k1
得:

x=inv(m1(m1,m2),m2(m1,m2))×(c2c1)(m1,m2)×m1+m1m2(m1,m2)×y+c1

xinv(m1(m1,m2),m2(m1,m2))×(c2c1)(m1,m2)×m1+c1 (mod m1m2(m1,m2))

推广一下

我们每次把两个同余式合并,求解之后得到一个新的同余式。再把新的同余式和其他的联立,最终就可以求出满足条件的解。

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

code
//#define int __int128
const int N = 1e5 + 10;
int n, M[N], C[N];
int gcd(int a, int b)
{
return !b ? a : gcd(b, a % b);
}
int exgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int inv(int a, int b)
{
int x, y;
exgcd(a, b, x, y);
return x < 0 ? x += b : x;
}
signed main()
{
rd(n);
for (int i = 1; i <= n; i ++ )
rd(M[i]), rd(C[i]);
bool flag = 1;
for (int i = 2; i <= n; i ++ )
{
int M1 = M[i - 1], M2 = M[i], C1 = C[i - 1], C2 = C[i], t = gcd(M1, M2);
if ((C2 - C1) % t != 0)
{
flag = 0;
break;
}
M[i] = (M1 * M2) / t;
C[i] = (inv(M1 / t, M2 / t) * (C2 - C1) / t) % (M2 / t) * M1 + C1;
C[i] = (C[i] % M[i] + M[i]) % M[i];
}
if (flag)
wr(C[n]);
else puts("");
return 0;
}

本文作者:kroyosh

本文链接:https://www.cnblogs.com/kroyosh/p/16611625.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kroyosh  阅读(38)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起