中国剩余定理(孙子定理)+ exgcd求逆元
中國剩余定理
??中國剩余定理又叫孫子定理。在《孫子算經(jīng)》中有這樣一個(gè)問題:“今有物不知其數(shù),三三數(shù)之剩二(除以3余2),五五數(shù)之剩三(除以5余3),七七數(shù)之 剩二(除以7余2),問物幾何?”這個(gè)問題稱為“孫子問題”,解決的孫子問題的一般解法就叫孫子定理又叫 天朝 中國剩余定理。
具體解法分兩步:
??1.找出3和5公倍數(shù)中除7余2的最小的數(shù)(30)、3和7公倍數(shù)中除5余3的最小的數(shù)(63)、5和7公倍數(shù)中除3余2的最小的數(shù)(140),然后將這三個(gè)數(shù)相加得233。(ps:為了簡(jiǎn)化運(yùn)算第一個(gè)數(shù)可以找 % 7 = 1的數(shù)之后在乘2,其他兩個(gè)數(shù)同理分別乘3、2。)
??而尋找取模后為1的數(shù)即為尋找其逆元,逆元的概念后面會(huì)說。
??2.用233除以3、5、7的最小公倍數(shù)105,得到余數(shù)23(即233%105 = 23),23即為所求。
是不是一臉懵(如果明明白白的請(qǐng)無視我這個(gè)菜雞),我第一次看也是想說就這么簡(jiǎn)單???
但這是有數(shù)學(xué)依據(jù)的:
??設(shè)這三個(gè)數(shù)分別為n1、n2、n3。因?yàn)閚1 % 7 == 2,n2、n3又都是7的倍數(shù)所以,(n1 + n2 + n3) % 7 == 2,其他兩個(gè)同理,所以最后得到的數(shù)233(n1+n2+n3)就滿足孫子問題中的三個(gè)條件,但這不一定是最小的解。
那么如何得到最小解?
??只需要在該解的基礎(chǔ)上最大限度的減去3、5、7的公倍數(shù)即可(即對(duì)該解取模233%105),為什么?因?yàn)檫@樣無論怎么減都不會(huì)影響其對(duì)于3、5、7的模數(shù)。
逆元
??給出 a 和 m ,一個(gè)數(shù)有逆元的充分必要條件是gcd(a,m)=1,此時(shí)逆元唯一存在,這時(shí)方程 ax ≡ 1(mod m)的最小整數(shù)解 x 稱為 a 模 m 的逆元。
??逆元的含義:
????在模m意義下,一個(gè)數(shù)a如果有逆元x,那么除以a相當(dāng)于乘x。
??為什么要有乘法逆元呢?
????當(dāng)我們要求(a/b) mod p的值,且a很大,大到會(huì)溢出;或者說b很大,達(dá)到會(huì)爆精度。無法直接求得a/b的值時(shí),我們就要用到乘法逆元。
??那么如何求解逆元呢?
????根據(jù)上文我們知道ax ≡ 1(mod m)有解的條件是a和m互素,即gcd(a,m) == 1.
????易知ax mod m = ax - (ax / m) * m
????所以ax ≡ 1(mod m) 等價(jià)于 ax - (ax / m) * m = 1
????提出m得
??????ax + m( - ax / m) = 1
????令y = -(ax/m)得
??????ax + my = 1
????所以求解 ax ≡ 1(mod m)等價(jià)于求解 ax + my = 1 ,那么就可以用擴(kuò)展歐幾里得定理求解。
擴(kuò)展歐幾里得定理(exgcd):
??給出整數(shù)a,b,n,求方程 ax + by = n 的所有整數(shù)解。有解的充分必要條件是gcd(a,b)可以整除 n 。簡(jiǎn)單解釋如下:
????令 a = gce(a,b) * a’、 b = gcd(a,b) * b’ , 則有 ax + by = gcd(a,b)(a’x + b’y) = n;如果 x 、y 、a’ 、b’都是整數(shù),那么n必須是gcd(a,b)的倍數(shù)才有整數(shù)解。
??exgcd解出的 x 為 ax + by = gcd(a,b) 中的 x ,若要求 ax + by = n中的 x,兩邊還要乘上 n / gcd(a,b)。
??由歐幾里得算法,得
????ax+by=gcd(a,b)=gcd(b,a mod b)=bx′+(a mod b)y′
??代入上文的a mod b = a - ? a / b ? b 得
?????ax + by = bx’ + (a - ? a / b ? b) y’
????????= bx’ + ay’ - ? a / b ? by’
????????= ay’ + b(x’ - ? a / b ?y’)
????得 x = y′ , y = x′ ? ? a / b ?y′
??邊界情況分析,ax′+by′=gcd(a,b),當(dāng) b=0 時(shí),a 為 gcd(a,b),當(dāng)且僅當(dāng) x′=1時(shí)等式成立,y′ 可以為任意值,為方便起見,設(shè)y′=0,那么得到以下代碼:
求出的 x 即為 a 模 b 的逆元。
介紹完了看看這道例題:
luogu 曹沖養(yǎng)豬
題目描述
自從曹沖搞定了大象以后,曹操就開始捉摸讓兒子干些事業(yè),于是派他到中原養(yǎng)豬場(chǎng)養(yǎng)豬,可是曹沖滿不高興,于是在工作中馬馬虎虎,有一次曹操想知道母豬的數(shù)量,于是曹沖想狠狠耍曹操一把。舉個(gè)例子,假如有 1616 頭母豬,如果建了 33 個(gè)豬圈,剩下 11 頭豬就沒有地方安家了。如果建造了 55 個(gè)豬圈,但是仍然有 11 頭豬沒有地方去,然后如果建造了 77 個(gè)豬圈,還有 22 頭沒有地方去。你作為曹總的私人秘書理所當(dāng)然要將準(zhǔn)確的豬數(shù)報(bào)給曹總,你該怎么辦?
輸入格式
第一行包含一個(gè)整數(shù) n (建立豬圈的次數(shù)),接下來 n 行,每行兩個(gè)整數(shù) ai,bi, 表示建立了 ai個(gè)豬圈,有 bi 頭豬沒有去處。你可以假定 ai,aj互質(zhì)。
輸出格式
輸出包含一個(gè)正整數(shù),即為曹沖至少養(yǎng)母豬的數(shù)目。
輸入
3 3 1 5 1 7 2輸出
16 #include<cstdio> #include<iostream> #include<cmath>#define ll long longusing namespace std;ll n,a[15],b[15],c[15],mul = 1,ans;void exgcd(ll a,ll b,ll &x, ll&y) {if(b == 0) {x = 1;y = 0;return;}exgcd(b,a%b,x,y);int z = x; x = y; y = z-y*(a/b); }int main( ) {scanf("%d",&n);for(int i = 1; i <= n; i++) {scanf("%d%d",&a[i],&b[i]);mul *= a[i];//求出所有數(shù)的最小公倍數(shù)(因?yàn)槊總€(gè)數(shù)都互質(zhì))}for(int i = 1; i <= n; i++) {c[i] = mul / a[i]; //除去a[i]所有數(shù)的最小公倍數(shù)ll x = 0, y = 0;exgcd(c[i],a[i],x,y);//求逆元ans += b[i] * c[i] * (x < 0 ? x + a[i]: x);//累加成其中一個(gè)解}printf("%lld",ans%mul);//輸出最小解return 0; }兩年沒寫博客了,如有錯(cuò)誤歡迎斧正。
總結(jié)
以上是生活随笔為你收集整理的中国剩余定理(孙子定理)+ exgcd求逆元的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 整理下如何获取WANmac和WAN口连接
- 下一篇: 使用hercules模拟IBM os39