码迷,mamicode.com
首页 > 其他好文 > 详细

中国剩余定理与扩展中国剩余定理

时间:2019-08-06 10:42:28      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:long   转化   mod   splay   return   lock   ==   剩余定理   art   

中国剩余定理(CRT)

我好蔡啊
不学这个东东我连任意模数\(NTT\)都学不了

问题

中国剩余定理用于求解同余方程组

\[ \left\{ \begin{aligned} x≡a_1(\mod m_1)\x≡a_2(\mod m_2)\......\x≡a_k(\mod m_k) \end{aligned} \right. \]

其中\(m_1,m_2,...,m_k\)两两互质
\(x\)的最小非负整数解

定理

\(M=\prod_{i=1}^km_i\),也就是它们的最小公倍数
\(t_i\)\({M\over m_i}t_i≡1(\mod m_i)\)的最小非负整数解
那么有一个\(x\)解为\(\sum_{i=1}^ka_i{M\over m_i}t_i\)
通解为\(x+kM(k\in \Z)\),最小非负整数解为\((x\% M+M)\%M\)

证明

对于\(M\over m_i\),它一定是其他\(m\)的倍数且不整除\(m_i\)(注意限制)
那么\(?k≠i,a_i{M\over m_i}t_i≡0(\mod m_k)\),这个是因为\({M\over m_i}\mod m_k=0\)
由于\({M\over m_i}t_i≡1(\mod m_i)\),所以\(a_i{M\over m_i}t_i≡a_i(\mod m_i)\)
又因为\(x=\sum_{i=1}^ka_i{M\over m_i}t_i\),代入方程组,方程组成立

code

容易发现因为\({M\over m_i}t_i≡1(\mod m_i)\)
其实就是求\({M\over m_i}\)关于\(m_i\)逆元
扩欧实现好了

inline ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if (b==0){x=1,y=0;return a;}
    ll ans=exgcd(b,a%b,y,x);
    y-=x*(a/b);return ans;
}
inline ll CRT(ll a[],ll m[],ll n)
{
    ll M=1ll,x,y,ans=0ll;
    fo(i,1,n)M*=m[i];
    fo(i,1,n)
    {
        ll tmp=M/m[i];exgcd(tmp,m[i],x,y);
        ans=(ans+a[i]*x*tmp)%M;
    }
    return (ans+M)%M;
}

扩展中国剩余定理(EXCRT)

问题

扩展中国剩余定理用于求解同余方程组

\[ \left\{ \begin{aligned} x≡a_1(\mod m_1)\x≡a_2(\mod m_2)\......\x≡a_k(\mod m_k) \end{aligned} \right. \]

其中\(m_1,m_2,...,m_k\)不保证两两互质
\(x\)的最小非负整数解

求解

设前\(k-1\)条方程组成的方程组的一个解为\(x\)
\(M=\prod_{i=1}^{k-1}m_i\),那么通解就为\(x+kM(k\in\Z)\)

那么考虑加入第\(k\)条方程,即求一个\(t\in\N^+\),使
\(x+tM≡a_k(\mod m_k)\),也就是\(tM≡a_k-x(\mod m_k)\)
由于\(M,a_k,x,m_k\)都已知,可以看作\(ax≡c(\mod b)\)
这个也可以用扩欧解

扩欧可以直接解出\(ax+by=gcd(a,b)\)的解\(x_0,y_0\)
于是如果直接解\(ax+by=c\)\(x_0\)还要除掉\({c\over \gcd(a,b)}\)就是\(x_0c\over \gcd(a,b)\)
原方程相当于\(ax\mod b=c\),转化为\(ax+by=c\),用上面的方法解就好了
注意如果不满足\(gcd(a,b)|c\),这条方程无解,整个方程组也无解
好像就是这样了,一共要做\(n-1\)次扩欧,注意各种取模细节

code

inline ll mul(ll x,ll y,ll mod)
{
    return (x*y-(ll)((long double)x/mod*y)*mod+mod)%mod;     
}
inline ll EXCRT(ll a[],ll m[],ll n)
{
    ll M=m[1],x,y,ans=a[1];
    fo(i,2,n)
    {
        ll gcd=exgcd(M,m[i],x,y),tmp=(a[i]-ans%m[i]+m[i])%m[i];
        if (tmp%gcd!=0)return -1;
        x=mul(x,tmp/gcd,m[i]/gcd);
        ans+=x*M,M*=m[i]/gcd,ans=(ans%M+M)%M;
    }
    return (ans%M+M)%M;
}

后记

感觉这种数学的东西还得多学多记多背……
本人版权意识薄弱……

中国剩余定理与扩展中国剩余定理

标签:long   转化   mod   splay   return   lock   ==   剩余定理   art   

原文地址:https://www.cnblogs.com/horizonwd/p/11307384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!