1. 程式人生 > >中國剩余定理

中國剩余定理

gcd 正整數 class 技術 普通 == http 百度 並且

設正整數技術分享兩兩互素,則同余方程組

技術分享

有整數解。並且在模技術分享下的解是唯一的,解為

技術分享

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

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

證明:可以參考百度百科。

中國剩余定理