日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[数论]Gcd/ExGcd欧几里得学习笔记

發布時間:2024/4/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [数论]Gcd/ExGcd欧几里得学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

\(Q\):什么是\(GCD\)?

  • \(GCD\)

\(GCD\),即最大公約數(\(Greatest\ Common\ Divisor\)

對于兩個自然數\(a,b\),定義\(GCD(a,b)\)\(a,b\)所有公共約數中最大的一個,即\(GCD(a,b)=\max\{x\in N^*,x|a\)\(x|b\}\)

然后是關于\(GCD\)的算法即其擴展


\(Part1\) 歐幾里得算法

\(Q\):這個算法有什么用?

此算法可以在\(log\)級別里求出兩個數\(a,b\)\(GCD\)

  • 歐幾里得算法

對于\(a,b\),設它們的\(GCD\)\(d\)

則有:\(d|a\)\(d|b\)

\(a=k*{}b+r(k=\left\lfloor\frac{a}{b}\right\rfloor,r=a\mod b)\)

則:\(d|(a-k*{}b)\),即\(d|r\)

所以\(GCD(a,b)=GCD(b,r)=GCD(b,a\mod b)\)

最后遞歸求解,可在\(O(log_2a)\)內得解。

時間復雜度 \(O(log_2a)\)

空間復雜度 \(O(log_2a)\)(遞歸棧)

實際復雜度一般到不了此上界。

代碼:

//求GCD(a,b) #include <cstdio>int GCD(int a,int b) {return b?GCD(b,a%b):a;//當b為0時,GCD(a,0)=a,充當遞歸邊界。 }int main() {int a,b;scanf("%d%d",&a,&b);printf("%d\n",GCD(a,b));return 0; }

\(Part2\) 擴展歐幾里得

\(Q\):這個奇怪的算法又是什么啊?

首先,先來看一個不定方程:

\[ax+by=c\]

擴展歐幾里得就是用來求此方程的不定解\((x,y)\)的。

準備知識:

  • \(Bezout\)定理

對于兩個整數\(a,b\)存在一對整數\(x,y\),滿足\(ax+by=GCD(a,b)\)

證明:

在調用歐幾里得算法時,當\(b=0\),顯然有\(x=1,y=0\)滿足定理。

\(b\not= 0\)時,若已經求得,\(x,y\),使得

\[bx+(a\mod b)y=GCD(b,a\mod b)\]

\[bx+(a-b\left\lfloor\frac{a}{b}\right\rfloor)y=GCD(b,a\mod b)\]

\[ay+b(x-\left\lfloor\frac{a}{b}\right\rfloor y)=GCD(b,a\mod b)\]

\(x'=y,y'=x-\left\lfloor\frac{a}{b}\right\rfloor y\),則有

\[ax'+by'=GCD(b,a\mod b)=GCD(a,b)\]

利用數學歸納法,知道\(Bezout\)成立。

同時,我們可以利用此定理求出一組\(ax+by=GCD(a,b)\)的解。

時間復雜度 \(O(log_2a)\)

空間復雜度 \(O(log_2a)\)

代碼:

//求x,y使得ax+by=GCD(a,b),同時得到GCD(a,b) #include <cstdio>int ExGCD(int a,int b,int &x,int &y) {if(!b){x=1,y=0;return a;}//遞歸邊界int GCD=ExGCD(b,a%b,x,y);int Tmp=x;x=y,y=Tmp-a/b*y;return GCD; }int main() {int a,b,GCD,x,y;scanf("%d%d",&a,&b);GCD=ExGCD(a,b,x,y);printf("%d %d %d\n",GCD,x,y);return 0; }

接著回到正題:對于方程\(ax+by=c\),它有解僅當\(GCD(a,b)|c\)

證明?不會,記住就行,畢竟顯然。

接著,求出方程\(ax+by=GCD(a,b)\)的一組解,則:

\[ax+by=GCD(a,b)\]

\[\frac{c}{GCD(a,b)}*{}(ax+by)=c\]

\[a*\frac{cx}{GCD(a,b)}+b*\frac{cy}{GCD(a,b)}=c\]

于是就有了一組解:\(x'=\frac{cx}{GCD(a,b)},y'=\frac{cy}{GCD(a,b)}\)(對\(x,y\)同時乘上\(\frac{c}{GCD(a,b)}\))

于是問題得解。

時間復雜度 \(O(log_2a)\)

空間復雜度 \(O(log_2a)\)

代碼:

//求x,y使得ax+by=c,同時得到GCD(a,b) #include <cstdio>int ExGCD(int a,int b,int &x,int &y) {if(!b){x=1,y=0;return a;}//遞歸邊界int GCD=ExGCD(b,a%b,x,y);int Tmp=x;x=y;y=Tmp-a/b*y;return GCD; }int main() {int a,b,c,GCD,x,y;scanf("%d%d%d",&a,&b,&c);GCD=ExGCD(a,b,x,y);if(c%GCD)return puts("Orz I cannot find it!"),0;//無解int d=c/GCD;printf("%d %d %d\n",GCD,x*d,y*d);return 0; }

關于通解以及\(x\)最小正整數解。

\(d=GCD(a,b)\)

\(x_0,y_0\)\(ax+by=GCD(a,b)\)的一組特解,

\(x=x_0+km,y=y_0+kn(k\in \mathbb{Z})\)為方程的通解表示(k為任意整數),

則:

\[ax+by=ax_0+by_0\]

\[a(x_0+km)+b(y_0+kn)=ax_0+by_0\]

\[am+bn=0\]

顯然,當\(m=-b,n=a\)時等式成立。

又因為要把\(m,n\)比例降到最小,所以同時除去\(GCD\)

最后的通解表示為:

\[x=x_0-k\frac{b}ozvdkddzhkzd,y=y_0+k\frac{a}ozvdkddzhkzd(k\in \mathbb{Z})\]

同理,對于方程\(ax+by=c\)的通解為:

\[x=\frac{c}ozvdkddzhkzdx_0-k\frac{b}ozvdkddzhkzd,y=\frac{c}ozvdkddzhkzdy_0+k\frac{a}ozvdkddzhkzd(k\in \mathbb{Z})\]

所以求\(x\)的最小整數解只需要將\(x\mod \frac{b}ozvdkddzhkzd\)再推出\(y\)即可。

時間復雜度 \(O(log_2a)\)

空間復雜度 \(O(log_2a)\)

代碼:

//求ax+by=c的x最小正整數解。 #include <cstdio>int ExGCD(int a,int b,int &x,int &y) {if(!b){x=1,y=0;return a;}//遞歸邊界int GCD=ExGCD(b,a%b,x,y);int Tmp=x;x=y;y=Tmp-a/b*y;return GCD; }int main() {int a,b,c,d,x,y;scanf("%d%d%d",&a,&b,&c);d=ExGCD(a,b,x,y);if(c%d)return puts("Orz I cannot find it!"),0;//無解x*=c/d,y*=c/d;int f=b/d;x=(x%f+f)%f;y=(c-a*x)/b;printf("%d %d\n",x,y);//x最小正整數解。return 0; }

所有性質證明到此結束。


歐幾里得是個好東西,然而我不會用。

數論博大精深,不能就此止步,還要繼續探索。

祝自己\(++OI::RP\)

轉載于:https://www.cnblogs.com/LanrTabe/p/10370627.html

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的[数论]Gcd/ExGcd欧几里得学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。