同余方程组
约 287 个字 34 行代码 预计阅读时间 1 分钟
一元线性同余方程组的形式¶
\begin{cases}x \equiv a_1 \pmod {n_1} \\x\equiv a_2 \pmod {n_2} \\... \\x\equiv a_k \pmod {n_k}\end{cases}
中国剩余定理(CRT)¶
前提条件¶
模数两两互质
算法流程¶
-
计算所有模数的积n=\prod\limits_{i=1}^k n_i
-
对于第 i 个方程:
- 计算m_i=n/n_i;
- 计算m_i在模n_i意义下的逆元m_i^{-1};
- 计算c_i=m_i*m_i^{-1}(不要对n_i取模)
-
方程组的唯一解为x=\sum\limits_{i=1}^k a_i*c_i \pmod n
时间复杂度¶
O(nlog n)
代码¶
long long CRT(int number,long long* remainder,long long* modulus)
{
long long m,x,y,product = 1, ans = 0;
for (int i = 1; i <= number; i++)
product = product * modulus[i];
for (int i = 1; i <= number; i++)
{
m = product / modulus[i];
exgcd(m, modulus[i], x, y);
ans = (ans + remainder[i] * m * x % product) % product;
}
return (ans % product + product) % product;
}
excrt¶
解决模数不互质的情况
原理¶
设两个方程分别是
x=a_1 \pmod {n_1}
x=a_2 \pmod {n_2}
将它们转化为不定方程
x=n_1*p+a_1=n_2*q+a2
其中 p , q 是整数
则有 n_1*p-n_2*q=a_2-a_1
由裴蜀定理,当a_2-a_1不能被gcd(n_1,n_2) 整除时,无解
有解时,可以通过 exgcd 解出来一组可行解 (p,q)
则原来的两方程组成的模方程组的解为
x=n_1*p+a_1 \pmod {lcm(n_1,n_2)}
多个方程,用上面的方法两两合并即可
代码¶
long long CRT(int number,long long* remainder,long long* modulus)
{
long long lcm = modulus[1],sum = remainder[1],x,y,gcd;
int fail = 0;
for(int i = 2;i <= number;++i)
{
remainder[i] = ((remainder[i] - sum) % modulus[i] + modulus[i]) % modulus[i];
gcd = exgcd(lcm,modulus[i],x,y);
if(remainder[i] % gcd == 0)
x = x * (remainder[i] / gcd) % modulus[i];
else
{
fail = 1;
break;
}
sum += x * lcm;
lcm = lcm / gcd * modulus[i];
sum = (sum % lcm + lcm) % lcm;
}
return fail ? -1 : sum;
}