1. 程式人生 > >擴充套件歐幾里得演算法,解模線性方程,解ax+by=c的解集

擴充套件歐幾里得演算法,解模線性方程,解ax+by=c的解集

typedef long long LL;
LL exgcd(LL a,LL b,LL &x,LL &y){
     if(a==0&&b==0) return -1;
     if(b==0) { x=1;y=0; return a;  }
     LL d=exgcd(b,a%b,y,x);
     y-=a/b*x;
     return d;
}
LL MLE(LL a,LL b,LL mod){  // 返回(a*x)%mod=b 的最小正整數解
    LL x,y;
    LL gcd=exgcd(a,mod,x,y);
    if(b%gcd!=0) return -1;  //若返回-1,則該方程無解
    x*=b/gcd;
    mod/=gcd;
    if(mod<0) mod=-mod;
    LL ans=x%mod;
    if(ans<=0) ans+=mod;  //其他解為: ans+i*mod (i為整數)
    return ans;
}
LL x0,y0,kx,ky;
bool LE(LL a,LL b,LL c){   //解線性方程ax+by=c
    LL x1,y1;
    LL gcd=exgcd(a,b,x1,y1);
    if(c%gcd)return false;  //無整數解
    x0=x1*c/gcd,y0=y1*c/gcd;
    kx=b/gcd,ky=-a/gcd;
    return true;   //有解,解集為:(x0+kx*t,y0+ky*t) t為整數
}


用擴充套件歐幾里德演算法求解模線性方程的方法:

    同餘方程 ax≡b (mod n)對於未知數 x 有解,當且僅當 gcd(a,n) | b。且方程有解時,方程有 gcd(a,n) 個解。

    求解方程 ax≡b (mod n) 相當於求解方程 ax+ ny= b, (x, y為整數)

    設 d= gcd(a,n),假如整數 x 和 y,滿足 d= ax+ ny(用擴充套件歐幾里德得出)。如果 d| b,則方程

    a* x0+ n* y0= d, 方程兩邊乘以 b/ d,(因為 d|b,所以能夠整除),得到 a* x0* b/ d+ n* y0* b/ d= b。
    所以 x= x0* b/ d,y= y0* b/ d 為 ax+ ny= b 的一個解,所以 x= x0* b/ d 為 ax= b (mod n ) 的解。

    ax≡b (mod n)的一個解為 x0= x* (b/ d ) mod n,且方程的 d 個解分別為 xi= (x0+ i* (n/ d ))mod n {i= 0... d-1}。

    設ans=x*(b/d),s=n/d;

    方程ax≡b (mod n)的最小整數解為:(ans%s+s)%s;

    相關證明:

    證明方程有一解是: x0 = x'(b/d) mod n;
    由 a*x0 = a*x'(b/d) (mod n)
         a*x0 = d (b/d) (mod n)   (由於 ax' = d (mod n))
                 = b (mod n)

    證明方程有d個解: xi = x0 + i*(n/d)  (mod n);
    由 a*xi (mod n) = a * (x0 + i*(n/d)) (mod n)
                             = (a*x0+a*i*(n/d)) (mod n)
                             = a * x0 (mod n)             (由於 d | a)
                             = b

首先看一個簡單的例子:

5x=4(mod3)

解得x = 2,5,8,11,14.......

由此可以發現一個規律,就是解的間隔是3.

那麼這個解的間隔是怎麼決定的呢?

如果可以設法找到第一個解,並且求出解之間的間隔,那麼就可以求出模的線性方程的解集了.

我們設解之間的間隔為dx.

那麼有

a*x = b(mod n);

a*(x+dx) = b(mod n);

兩式相減,得到:

a*dx(mod n)= 0;

也就是說a*dx就是a的倍數,同時也是n的倍數,即a*dx是a 和 n的公倍數.為了求出dx,我們應該求出a 和 n的最小公倍數,此時對應的dx是最小的.

設a 和 n的最大公約數為d,那麼a 和 n 的最小公倍數為(a*n)/d.

即a*dx = a*n/d;

所以dx = n/d.

因此解之間的間隔就求出來了.



相關推薦

擴充套件演算法線性方程ax+by=c

typedef long long LL; LL exgcd(LL a,LL b,LL &x,LL &y){ if(a==0&&b==0) return -1

演算法複習——擴充套件演算法擴充套件逆元整除)

①歐幾里得演算法 就是求gcd的有趣的輾轉相除法,不再贅述啦0v0 程式碼: int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); } ②擴充套件歐幾里得演算法 需要解決這樣的問題:兩個非0整數a,b

擴充套件演算法+獲取特殊的

通過擴充套件歐幾里得演算法獲取x或者y的最小整數解 template<class T> void exgcd(T a,T b,T &d,T &x,T &y){ if(!b) {d=a;x=1;y=0;} else {exgcd(b,a%b,d,y,x

的個數(直線上的點)(數論-擴充套件演算法

Description  已知x,y滿足如下條件:  ax+by+c=0 ; x1 <= x <= x2 ; y1 <= y <= y2 ; x,y均為整數。  其中:a,b,c,x1,x2,y1,y2 都是絕對值不超過 10^8 的整數。  求(x,

擴充套件演算法(乘法逆元 最小正整數 直線上的整數點)

參考資料: 本文證明過程來自百度百科和劉汝佳的演算法入門經典。 擴充套件歐幾里得演算法介紹: 前置知識:歐幾里得演算法(其實就是輾轉相除法,用於計算兩個整數a,b的最大公約數。) 歐幾里得演算法: 在開始之前,我們先說明幾個定理: gcd(a,b)=gcd(b,a

乘法逆元詳【費馬小定理+擴充套件演算法

乘法逆元 何為乘法逆元? 對於兩個數a,pa,p若gcd(a,p)=1gcd(a,p)=1則一定存在另一個數bb,使得ab≡1(modp)ab≡1(modp),並稱此時的bb為aa關於11模pp的乘法逆元。我們記此時的bb為inv(a)inv(a)或a−1a

POJ 1061 擴充套件演算法不定方程

貼一個題目地址吧:http://poj.org/problem?id=1061 (下文對擴充套件歐幾里得演算法的論述基本取決於所打的程式碼模板,故不準確) 抽象題意。設青蛙跳過的圈數為K,青蛙跳的次數為T。 根據題意有X+MT ≡ Y+NT(mod L)==> LK

擴充套件演算法

為了介紹擴充套件歐幾里得,我們先介紹一下貝祖定理:            即如果a、b是整數,那麼一定存在整數x、y使得ax+by=gcd(a,b)。 換句話說,如果ax+by=m有解,那麼m一定是gcd(a,b)的若干倍。(可以來判斷一個這樣的式子有沒有解) 有一個直

UVA - 12169 -擴充套件演算法

#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #define ll long long #define rep(i,j,k) for(int i=j;

實驗二 擴充套件演算法c++程式碼

#include<iostream> #include<stdio.h> using namespace std; int x,y,q; void extend_Eulid(int a,int b) { if(b==0) { x=1; y=0; q=a; }

擴充套件演算法】輾轉相除法

其計算原理依賴於下面的定理: 定理:兩個整數的最大公約數等於其中較小的那個數和兩數相除餘數的最大公約數。最大公約數(Greatest Common Divisor)縮寫為GCD。 /* 歐幾里德演算法:輾轉求餘 原理: gcd(a,b)=gcd(b,a mod b) 當b為0時,兩數的最

POJ-1061-青蛙的約會 (擴充套件演算法

原題連結: http://poj.org/problem?id=1061 兩隻青蛙在網上相識了,它們聊得很開心,於是覺得很有必要見一面。它們很高興地發現它們住在同一條緯度線上,於是它們約定各自朝西跳,直到碰面為止。可是它們出發之前忘記了一件很重要的事情,既沒有問清楚對方的特徵,也沒有約定

HDU-2669-Romantic (擴充套件演算法

原題連結: http://acm.hdu.edu.cn/showproblem.php?pid=2669 The Sky is Sprite. The Birds is Fly in the Sky. The Wind is Wonderful. Blew Throw the Trees

POJ-2142-The Balance (擴充套件演算法

原題連結: Ms. Iyo Kiffa-Australis has a balance and only two kinds of weights to measure a dose of medicine. For example, to measure 200mg of aspiri

擴充套件演算法--C語言程式

前提 擴充套件歐幾里得演算法是在歐幾里得演算法(輾轉相除法)的前提下,對已知數求係數的一種演算法。擴充套件歐幾里得演算法的公式推導我就不廢話了,基本上就是第一次推導的係數等於第二次推導的係數之間的聯絡,很多文章都引用百度對擴充套件歐幾里得的定義,但是講的不是很

擴充套件演算法python版

程式功能:             輸入兩個數m,n  (m>n)             輸出他們的最大公約數,同時輸出s,t ( m*s + n*t = 1)  #-*-coding:u

擴充套件演算法(求乘法逆元)

eg:求5關於模14的乘法逆元 15 = 5*2+1 5 = 4*1+1 說明5與14互素,存在5關於14的乘法逆元 1 = 5-4 = 5-(14-5*2)= 5*3-14 因此5關於模14的乘法逆元為3  a存在模b的乘法逆元的充要條件是gcd(a,b)= 1 互質

擴充套件演算法——exgcd

擴充套件歐幾里德演算法是用來在已知a,ba,ba,b求解一組x,yx,yx,y,使它們滿足貝祖(裴蜀)等式: ax+by=gcd(a,b)=dax+by = gcd(a, b) =dax+by=gcd(a,b)=d 試著來搞一下 ax+by=gcd(a,b

【未完成】除法取、逆元、擴充套件演算法

1.+,-,*都可以直接取模,但是除法不可以(模素數相當於換了數域,因為數域變成了有限域,有限域上沒有除法,要換成乘以逆元)。 2.除法取模要變成乘它的逆元。 a * x MOD m == 1則稱X為A關於模m的乘法逆元,其中a和m必須互素。 3.當m為素數時可以使用

演算法學習(一)——演算法&擴充套件演算法

最大公約數/歐幾里德演算法(gcd) 歐幾里德演算法又稱輾轉相除法,證明可以度娘。 個人簡單腦部就是a和b兩個數的模還是a和b的最大公約數 int型別  int gcd(int a, int b) {return a%b==0?b:gcd(b,a%b);} long l