中國剩余定理


中國剩余定理

有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何?即,一個整數除以三余二,除以五余三,除以七余二,求這個整數。

《孫子算經》中首次提到了同余方程組問題,以及以上具體問題的解法,因此在中文數學文獻中也會將中國剩余定理稱為孫子定理。

換句話說:“一個正整數除以3余2,除於5余3,除於7余2,求這個正整數是幾?”

基本解法:

1)先找到除以3余2,除於7余2的數是那些。經過分析得到滿足要求的數是21的倍數加2。

       2,23,44,65,96,107,........

2)在上述結果中繼續尋找除以5余3的數。

3)滿足上述要求的正整數是:23,128,233,338

這里 128-23=105  正好是[3,5,7]的最小公倍數

古人的解法:

先找5和7的公倍數中除以3余1的數:70

再找3和7的公倍數中除以5余1的數:21

再找3和5的公倍數中除以7余1的數:15

70*2+21*3+15*2=233

233-105=128

128-105=23

所以這個正整數最小是23.

 

先考慮問題的分解:

問題1:計算一個整數 [公式] ,使得它滿足除以3余2、除以5余3、除以7余2。

如果能夠找到三個整數 [公式] ,使得:

[公式] 除以3余2、除以5余0、除以7余0;

[公式] 除以3余0、除以5余3、除以7余0;

[公式] 除以3余0、除以5余0、除以7余2;

那么令 [公式] ,就很容易驗證這時的 [公式] 就滿足除以3余2、除以5余3、除以7余2。

分別稱找到整數 [公式] 的問題為問題1-1、問題1-2、問題1-3。可以看出這三個問題本質上是類似的。

 

 

普通的中國剩余定理要求所有的互素,那么如果不互素呢,怎么求解同余方程組?

  這種情況就采用兩兩合並的思想,假設要合並如下兩個方程:

  那么得到:

  我們需要求出一個最小的xx使它滿足:

  那么x1x1和x2x2就要盡可能的小,於是我們用擴展歐幾里得算法求出x1x1的最小正整數解,將它代回a1+m1x1,得到x的一個特解x,當然也是最小正整數解。

  所以xx的通解一定是x加上lcm(m1,m2)k,這樣才能保證xm1m2的余數是a1a2。由此,我們把這個xx′當做新的方程的余數,把lcm(m1,m2)當做新的方程的模數。(這一段是關鍵

  合並完成:

代碼:

#include<bits/stdc++.h>
using namespace std; int const MAXN=10010; int x,y; int k;//k組同余方程
int a[MAXN];//每個同余方程的余數
int b[MAXN];//每個同余方程的模數
int ans; int lcm=1; void exgcd(int a,int b) { if(b==0){x=1;y=0;} else{ exgcd(b,a%b); int tmp=x; x=y; y=tmp-a/b*y; } return; } int main() { cin>>k; for(int i=1;i<=k;++i) cin>>b[i]>>a[i]; for(int i=1;i<=k;++i) lcm*=b[i]; for(int i=1;i<=k;++i) { exgcd(lcm/b[i],b[i]); x=(x%b[i]+b[i])%b[i]; ans=(ans+(lcm/b[i])*x*a[i])%lcm; } cout<<ans; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM