歐幾里德&&擴(kuò)展歐幾里德

歐幾里得算法:
遞歸版本:

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

迭代版本:

int gcd(int a,int b)
{
    while(b!=0)
    {
        int r=b;
        b=a%b;
        a=r;
    }
    return a;
}

擴(kuò)展歐幾里德算法:
基本算法:對(duì)于不完全為 0 的非負(fù)整數(shù) a狰贯,b也搓,gcd(a赏廓,b)表示 a,b 的最大公約數(shù)傍妒,必然存在整數(shù)對(duì) x幔摸,y ,使得 gcd(a颤练,b)=ax+by既忆。

證明:設(shè) a>b。
  1昔案,顯然當(dāng) b=0尿贫,gcd(a,b)=a踏揣。此時(shí) x=1庆亡,y=0;
  2捞稿,ab!=0 時(shí)
  設(shè) ax1+by1=gcd(a,b);
  bx2+(a mod b)y2=gcd(b,a mod b);
  根據(jù)樸素的歐幾里德原理有 gcd(a,b)=gcd(b,a mod b);
  則:ax1+by1=bx2+(a mod b)y2;
  即:ax1+by1=bx2+(a-(a/b)b)y2=ay2+bx2-(a/b)*by2;
  根據(jù)恒等定理得:x1=y2; y1=x2-(a/b)y2;
這樣我們就得到了求解 x1,y1 的方法:x1又谋,y1 的值基于 x2,y2.

int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int res=exgcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return res;
}

擴(kuò)展歐幾里德算法的應(yīng)用主要有以下三方面:
(1)求解不定方程娱局;
(2)求解模線性方程(線性同余方程)彰亥;
(3)求解模的逆元;

(1)使用擴(kuò)展歐幾里德算法解決不定方程的辦法:
對(duì)于不定整數(shù)方程a*x+b*y=c,若 c mod Gcd(x, y)=0,則該方程存在整數(shù)解衰齐,否則不存在整數(shù)解任斋。 上面已經(jīng)列出找一個(gè)整數(shù)解的方法,在找到 a*x+ b*y = Gcd(a,b)的一組解x0,y0后耻涛,
a*x+b*y = Gcd(a, b)的其他整數(shù)解滿足:
x = x0 + b/Gcd(a, b) * t
y = y0 - a/Gcd(a, b) * t(其中t為任意整數(shù))
因?yàn)閍*x+b*y=a(x0 + b/Gcd(a, b) * t)+b(y0 - a/Gcd(a, b) * t)=Gcd(a,b)

其中废酷,最小的正整數(shù)x為: x=x0%( b/Gcd(a, b) )
最小的正整數(shù)y: y=y0%( a/Gcd(a, b) )

至于ax+by=c的整數(shù)解,只需將a*x+b*y= Gcd(a,b)的每個(gè)解乘上 c/Gcd(a,b) 即可抹缕。

用擴(kuò)展歐幾里得算法解不定方程ax+by=c;

bool linear_equation(int a,int b,int c,int &x,int &y)
{
    int d=exgcd(a,b,x,y);
    if(c%d)
        return false;
    int k=c/d;
    x*=k; y*=k;    //初解
  /*
  x=x+b/(gcd(a,b))*t;//其他解
  y=y-a/(gcd(a,b))*t;
  t為任意整數(shù)
  */
    return true;
}

(2)用擴(kuò)展歐幾里德算法求解模線性方程的方法:
同余方程 ax≡b (mod n),即(a*x-b) mod n=0;推出a*x+n*y=b;所以轉(zhuǎn)化為求不定方程a*x+n*y=Gcd(a,n)澈蟆。
如果b%(Gcd(a,n))!=0,那么方程無(wú)整數(shù)解;否則求出初解x0,然而初值還要乘以b/Gcd(a,n),即x=x0*b/Gcd(a,n)才是方程a*x+n*y=b的解
而其他整數(shù)解則滿足:
x(i) = x + b/Gcd(a, b) * t
y(i) = y - a/Gcd(a, b) * t (其中t為任意整數(shù))

bool modular_linear_equation(int a,int b,int n)
{
    int x,y,x0,i;
    int d=exgcd(a,n,x,y);
    if(b%d)
        return false;
    x0=x*(b/d)%n;   //特解
    for(i=1;i<d;i++)
        printf("%d\n",(x0+i*(n/d))%n);
    return true;
}

(3)用歐幾里德算法求模的逆元:
乘法逆元:如果a*x≡1 (mod p),且gcd(a,p)=1(a與p互質(zhì)),則稱a關(guān)于模p的乘法逆元為x卓研。
它的同余方程ax+py=gcd(a,p)=1,而1%1==0,所以肯定有解

LL exgcd(LL a,ll b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    ll gcd=exgcd(b,a%b,x,y);
    ll temp=x;
    x=y;
    y=temp-a/b*y;
    return gcd;
}
LL reverseMod(LL a,LL mod)
{
    LL x,y;
    LL d=exgcd(a,mod,x,y);//求初解x
    //其他解為x(i) = x+b/Gcd(a, b)*t=x+mod/1*t=x+mod*t
    while(x<0) x+=mod;//求出一個(gè)x>0的逆元
    return x;

} 

( 4 )用費(fèi)馬小定理求乘法逆元趴俘。
由費(fèi)馬小定理a^(p-1)≡ 1(mod p)(p為素?cái)?shù)),稍作變形即是 a*a^(p-2)≡ 1(mod p)奏赘,是不是發(fā)現(xiàn)了寥闪,a^(p-2)即是a的逆元,這個(gè)可以用快速冪來(lái)求磨淌。

typedef long long LL;
LL fast_multi(LL a,LL b,LL mod)
{
    LL res=0,base=a;
    while(b)
    {
        if(b&1) res=(res+base)%mod;
        b>>=1;
        base=(base+base)%mod;
    }
    return res;
}
LL pow_mod(LL a,LL b,LL mod)
{
    LL res=1,base=a;
    while(b)
    {
        if(b&1) res=fast_multi(res,base,mod);
        base=fast_multi(base,base,mod);
        b>>=1;
    }
    return res;
}//b關(guān)于對(duì)mod取模的逆元為pow_mod(b,mod-2,mod);

題目:求(a/b)%mod疲憋。
題解:先求出b的逆元,然后結(jié)果為(a*(b^-1) )%mod伦糯,b^-1指b關(guān)于對(duì)mod取模運(yùn)算的逆元

#include<stdio.h>
#include <string.h>
using namespace std;
const long long mod=9973;//一個(gè)素?cái)?shù)
typedef long long LL;
LL fast_multi(LL a,LL b,LL mod)
{
    LL res=0,base=a;
    while(b)
    {
        if(b&1) res=(res+base)%mod;
        b>>=1;
        base=(base+base)%mod;
    }
    return res;
}
LL pow_mod(LL a,LL b,LL mod)
{
    LL res=1,base=a;
    while(b)
    {
        if(b&1) res=fast_multi(res,base,mod);
        base=fast_multi(base,base,mod);
        b>>=1;
    }
    return res;
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    LL gcd=exgcd(b,a%b,x,y);
    LL temp=x;
    x=y;
    y=temp-a/b*y;
    return gcd;
}
LL reverseMod(LL a,LL mod)
{
    LL x,y;
    LL d=exgcd(a,mod,x,y);
    while(x<0) x+=mod;
    return x;

}
int main()
{
    int n;
    LL a,b,x;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lld%lld",&a,&b);
        x=reverseMod(b,mod);
        printf("%lld\n",fast_multi(a,x,mod));//擴(kuò)展歐里幾德
        printf("%lld\n",fast_multi(a,pow_mod(b,mod-2,mod),mod));//費(fèi)馬小定理
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柜某,一起剝皮案震驚了整個(gè)濱河市嗽元,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喂击,老刑警劉巖剂癌,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異翰绊,居然都是意外死亡佩谷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門监嗜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谐檀,“玉大人,你說(shuō)我怎么就攤上這事裁奇⊥┾” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵刽肠,是天一觀的道長(zhǎng)溃肪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)音五,這世上最難降的妖魔是什么惫撰? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮躺涝,結(jié)果婚禮上厨钻,老公的妹妹穿的比我還像新娘。我一直安慰自己坚嗜,他們只是感情好夯膀,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惶傻,像睡著了一般棍郎。 火紅的嫁衣襯著肌膚如雪其障。 梳的紋絲不亂的頭發(fā)上银室,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音励翼,去河邊找鬼蜈敢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛汽抚,可吹牛的內(nèi)容都是我干的抓狭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼造烁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼否过!你這毒婦竟也來(lái)了午笛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苗桂,失蹤者是張志新(化名)和其女友劉穎药磺,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煤伟,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡癌佩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了便锨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片围辙。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖放案,靈堂內(nèi)的尸體忽然破棺而出姚建,到底是詐尸還是另有隱情,我是刑警寧澤吱殉,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布桥胞,位于F島的核電站,受9級(jí)特大地震影響考婴,放射性物質(zhì)發(fā)生泄漏贩虾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一沥阱、第九天 我趴在偏房一處隱蔽的房頂上張望缎罢。 院中可真熱鬧,春花似錦考杉、人聲如沸策精。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咽袜。三九已至,卻和暖如春枕稀,著一層夾襖步出監(jiān)牢的瞬間询刹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工萎坷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凹联,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓哆档,卻偏偏與公主長(zhǎng)得像蔽挠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓜浸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容