中国剩余定理 $CRT$

考虑一个同余方程组
\[ \begin{cases}x \equiv a_1 \ (mod \ b_1) \\x \equiv a_2 \ (mod \ b_2) \\\quad \quad \quad \vdots \\x \equiv a_n \ (mod \ b_n) \end{cases} \]

其中\(b_1,b_2,\dots,b_n\)两两互质。

\(m = \prod\limits_{i = 1}^n b_i\)\(M_i = \frac{m}{b_i}\)\(t_i\)是同余方程\(xM_i \equiv 1 \ (mod \ b_i)\)的一个解

那么上面那个方程组的解为\(\sum\limits_{i = 1}^{n} a_i M_i t_i\)

证明:

考虑\(\sum\)中的一项\(i\),对于\(k = i\)显然有\(a_i M_i t_i \equiv a_k \ (mod \ b_k)\),若\(k \not = i\),则\(a_i M_i t_i \equiv 0 \ (mod \ b_k)\)(因为\(M_i\)是其他\(b\)的乘积)。

所以上面\(\Sigma\)中的\(n\)项各会满足一个方程,且不会对其他有影响,故\(x = \sum\limits_{i = 1}^{n} a_i M_i t_i\)是一组合法解。

证毕。

另外,\(x\)是在\(mod \ m\)意义下的解,即解集可以表示为\(\{x + km : k \in \Z\}\)


板子题

\(Code\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mult(ll a,ll b,ll c){
    if (b>a) swap(a,b);
    ll ret=0; for (;b;b>>=1,a=a*2%c) if (b&1) ret=(ret+a)%c;
    return ret;
}
void exgcd(ll a,ll b,ll &x,ll &y){
    if (b==0){x=1,y=0;return;}
    else{
        exgcd(b,a%b,x,y);
        ll tmp=x; x=y; y=tmp-a/b*x;
    }
}
ll a[110],b[110]; int n;
ll CRT(){
    ll m=1; for (int i=1;i<=n;i++)m*=b[i];
    for (int i=1;i<=n;i++) a[i]=(a[i]%m+m)%m;
    ll ans=0;
    for (int i=1;i<=n;i++){
        ll Mi=m/b[i],t,tmp;
        exgcd(Mi,b[i],t,tmp);
        t=(t%m+m)%m;
        ans=(ans+mult(Mi,mult(t,a[i],m),m))%m;
    }
    return ans;
}
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for (int i=1;i<=n;i++) scanf("%lld",&b[i]);
    printf("%lld\n",CRT());
    return 0;
}

待填:扩展中国剩余定理 \(ExCRT\)

猜你喜欢

转载自www.cnblogs.com/wxq1229/p/12232491.html