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

中国剩余定理

时间:2017-07-30 20:32:11      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:ret   for   中国剩余定理   int   算法   log   logs   整数   同余方程   

设正整数技术分享两两互素,则同余方程组

 

                             技术分享

 

有整数解。并且在模技术分享下的解是唯一的,解为

 

                               技术分享

 

其中技术分享,而技术分享技术分享技术分享的逆元。

ll e_gcd(ll a,ll b,int &x,int &y){
    if (b==0){
        x=1; y=0; return a;
    }
    ll d=e_gcd(b,a%b,x,y);
    ll t=x; x=y;
    y=t-(a/b)*y;
    return d;
}
void CRT(int n){
    int M=1; ans=0;
    for (int i=1;i<=n;i++) M*=m[i];
    for (int i=1;i<=n;i++){
        int x,y,Mi=M/m[i];
        e_gcd(Mi,m[i],x,y);
        ans=mo(ans+a[i]*Mi*x,M);
    } 
}

 

普通的中国剩余定理要求所有的技术分享互素,那么如果不互素呢,怎么求解同余方程组?

 

这种情况就采用两两合并的思想,假设要合并如下两个方程

 

      技术分享

 

那么得到

 

       技术分享

 

在利用扩展欧几里得算法解出技术分享的最小正整数解,再带入

 

       技术分享

 

得到技术分享后合并为一个方程的结果为

 

       技术分享

 

这样一直合并下去,最终可以求得同余方程组的解。

ll e_gcd(ll a,ll b,ll &x,ll &y){
    if (b==0){
        x=1; y=0; return a;
    }
    ll d=e_gcd(b,a%b,x,y);
    ll t=x; x=y;
    y=t-(a/b)*y;
    return d;
}
ll e_crt(int n)
{
    ll M=m[1],R=r[1],x,y,d;
    for (int i=2;i<=n;++i)
    {
        d=e_gcd(M,m[i],x,y);
        if ((r[i]-R)%d) return -1;
        x=(r[i]-R)/d*x%(m[i]/d);
        R+=x*M; M=M/d*m[i]; R%=M;
    }
    return R>0?R:R+M;
}

转自:http://blog.csdn.net/acdreamers/article/details/8050018

证明:可以参考百度百科。

 

中国剩余定理

标签:ret   for   中国剩余定理   int   算法   log   logs   整数   同余方程   

原文地址:http://www.cnblogs.com/SXia/p/7260239.html

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