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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

exgcd 学习笔记

發(fā)布時(shí)間:2023/12/24 windows 59 coder
生活随笔 收集整理的這篇文章主要介紹了 exgcd 学习笔记 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

定義

又名擴(kuò)展歐幾里得算法(輾轉(zhuǎn)相除法)

是用來(lái)求 \(ax+by=gcd(a,b)\) 中未知數(shù)的算法


算法證明

拿到一組 \(a,b\) ,設(shè) \(G=gcd(a,b)\)

目標(biāo):求出滿足 \(ax+by=G(1)\)\(x\)\(y\)

如果 已知一組 \(x2,y2\) ,滿足 \(bx2+\) \((a\) \(mod\) \(b)y2=G(2)\)

此時(shí)結(jié)合 \((1)(2)\)
\(ax+by=\) \(bx2+\) \((a\) \(mod\) \(b)y2(3)\)

那么當(dāng) 如果 滿足時(shí),目標(biāo)就成了求滿足 \((3)\)\(x,y\),其中 \(a,b,x2,y2\) 均已知

根據(jù)取模運(yùn)算是 \(a\) \(mod\) \(b=a-b*(a/b)\)
所以方程 \((3)\) 實(shí)則是

\(ax+by=\) \(bx2+\) \((a-b*(a/b))y2\)

\(->\) \(ax+by=bx2+ay2-b*(a/b)y2\)

\(->\) \(ax+by=ay2+b(x2-(a/b)y2)\)

那么在根據(jù)方程 \(ax+by=G(1)\) 得出一組必然的解:

\(x=y2,y=x2-(a/b)y2(4)\)

可見(jiàn)只需求出 \(x2,y2\) ,就能求出正確的 \(x,y\),問(wèn)題就轉(zhuǎn)化成了求 \(x2,y2\)

將方程 \((1)\)\((2)\) 對(duì)比一下:

\(ax+by=G(1)\)

\(bx2+\) \((a\) \(mod\) \(b)y2=G(2)\)

發(fā)現(xiàn)原方程的 \(a\) 變成了 \(b\),原方程的 \(b\) 變成了 \(a\) 而已

所以新的方程也可以看做 \(ax+by=G\) 的形式,然后按照上面的程序進(jìn)行下來(lái),發(fā)現(xiàn)問(wèn)題又變?yōu)榍?\(x3,y3\) 再求 \(x4,y4\) \(......\) 即一個(gè)遞歸的過(guò)程

遞歸過(guò)程中 \(a,b\) 不斷被替換為 \(b,a\) \(mod\) \(b\),這個(gè)過(guò)程和普通的歐幾里得是一樣的,所以最后會(huì)出現(xiàn) \(a(n)=G,b(n)=0\)

那么這特就是最后一層,此時(shí)就要直接返回了,需要一組 \(x(n),y(n)\) 滿足 \(a(n)x(n)+b(n)y(n)=G(5)\),然而 \(a(n)=G,b(n)=0\),所以只要 \((5)\)\(x(n)\)\(1\) 就必定滿足了,\(y(n)\) 就隨便取個(gè) \(0\) 就行了

最后一層結(jié)束后,就開始返回,知道最上一層,每一層都可以通過(guò)下一層的 \(x(k+1),y(k+1)\) 求出當(dāng)前層的 \(x(k),y(k)\)

整個(gè)過(guò)程就是:以輾轉(zhuǎn)相除的方式向下遞進(jìn),不斷縮小系數(shù),保證會(huì)出現(xiàn)有確定解的最后一層


例題

題目鏈接 同余方程

問(wèn)題處理

題目問(wèn)的是滿足 \(ax\) \(mod\) \(b=1\) 的最小正整數(shù)(a,b均為正整數(shù))

問(wèn)題可以轉(zhuǎn)化成求 \(ax+by=1\)\(x\) 的值,其中 \(y\) 是個(gè)引入的輔助數(shù)(y一定是一個(gè)負(fù)數(shù),但是寫成 \(+\) 的形式以便 \(exgcd\) 算法)

問(wèn)題仍需轉(zhuǎn)化,\(exgcd\) 求得是 \(ax+by=gcd(a,b)\),所以求方程 \(ax+by=m\) 必須滿足的條件就是 \(m\) \(mod\) \(gcd(a,b)=0\)


簡(jiǎn)單證明一下:

由最大公因數(shù)的定義,\(a,b\) 均是 \(gcd(a,b)\) 的倍數(shù),因?yàn)?\(m=ax+by\),所以 \(m\) 一定是 \(gcd(a,b)\) 的倍數(shù),即 \(m\) \(mod\) \(gcd(a,b)=0\)


可得這道題中,必須滿足 \(1\) \(mod\) \(gcd(a,b)=0\),那么 \(gcd(a,b)\) 就必須等于 \(1\) 了,即 \(a,b\) 互質(zhì)(數(shù)據(jù)一定是滿足的)

之后通過(guò)上述的 \(exgcd\) 算法即可,但是題目要求 \(x\) 的最小值,僅僅 \(exgcd\) 無(wú)法滿足,所以需要答案處理


答案處理

求出來(lái)的 \(x,y\) 僅僅滿足 \(ax+by=1\),而 \(x\) 不一定是最小正整數(shù)解。有可能太大,也可能是負(fù)數(shù)

解決方案是:\(x\) 批量地減去或加上 \(b\),能保證 \(ax+by=1\),因?yàn)椋?/p>

\(ax+by=1\)

\(->\) \(ax+by+k*ba-k*ba=1\)

\(->\) \(a(x+kb)+(y-ka)b=1\)

1.顯然這并不會(huì)把方程中的任何整數(shù)變?yōu)榉钦麛?shù)

2.加上或減去 \(b\) 不會(huì)使 \(x\) 錯(cuò)過(guò)任何解,可以這么理解:


已經(jīng)求出一組 \(x,y\) 使得 \(ax+by=1\),也就是 \((1-ax)/b=y\)\(y\) 是整數(shù),可見(jiàn)目前 \(1-ax\)\(b\) 的倍數(shù)

現(xiàn)在給 \(x\) 加上 \(kb\)(k為整數(shù)),則變?yōu)椋?/p>

\((1-a(x+kb))/b\)

\(=(1-ax)/b+ak\)

仍滿足其為 \(b\) 的倍數(shù),由此當(dāng) \(x\) 的變化量為 \(b\) 的倍數(shù)時(shí),等式仍滿足


因此到最后,如果 \(x\) 太小就不斷 \(+b\) 直到 \(>=0\),反之則一直減直到最小正整數(shù)值,就是這么寫

x=(x%b+b)%b;

總代碼如下

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
template<typename Tp> inline void read(Tp&x)
{
    x=0;register bool z=1;
    register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
    for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    x=(z?x:~x+1);
}
int a,b,x,y;
int exgcd(int a,int b,int &x,int &y)
{
    if(b==0) {x=1;y=0;return a;}
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
signed main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    read(a),read(b);
    exgcd(a,b,x,y);
    x=(x%b+b)%b;
    cout<<x;
}

總結(jié)

以上是生活随笔為你收集整理的exgcd 学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。