1. 程式人生 > >拓展歐幾裏得算法

拓展歐幾裏得算法

for tar 方法 應該 擴展歐幾裏得算法 amp gpo 線性同余 pre

擴展歐幾裏德算法的應用主要有以下三方面:

(1)求解不定方程;

(2)求解模線性方程(線性同余方程);

(3)求解模的逆元;

遞歸形式:

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

非遞歸形式:

 1 int exgcd(int m,int n,int
&x,int &y) 2 { 3 int x1,y1,x0,y0; 4 x0=1; y0=0; 5 x1=0; y1=1; 6 x=0; y=1; 7 int r=m%n; 8 int q=(m-r)/n; 9 while(r) 10 { 11 x=x0-q*x1; y=y0-q*y1; 12 x0=x1; y0=y1; 13 x1=x; y1=y; 14 m=n; n=r; r=m%n; 15 q=(m-r)/n; 16 } 17 return
n; 18 }

(1)使用擴展歐幾裏德算法解決不定方程的辦法:

對於不定整數方程pa+qb=c,若 c mod Gcd(p, q)=0,則該方程存在整數解,否則不存在整數解。
上面已經列出找一個整數解的方法,在找到p * a+q * b = Gcd(p, q)的一組解p0,q0後,p * a+q * b = Gcd(p, q)的其他整數解滿足:
p = p0 + b/Gcd(p, q) * t
q = q0 - a/Gcd(p, q) * t(其中t為任意整數)
至於pa+qb=c的整數解,只需將p * a+q * b = Gcd(p, q)的每個解乘上 c/Gcd(p, q) 即可。

在找到p * a+q * b = Gcd(a, b)的一組解p0,q0後,應該是得到p * a+q * b = c的一組解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),

p * a+q * b = c的其他整數解滿足:

p = p1 + b/Gcd(a, b) * t q = q1 - a/Gcd(a, b) * t(其中t為任意整數) p 、q就是p * a+q * b = c的所有整數解。 用擴展歐幾裏得算法解不定方程ax+by=c; 代碼如下:

898B. Proper Nutrition

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAX_N = 1e5+9;
 4 long long  exgcd(long long  m,long long  n,long long  &x,long long  &y)
 5 {
 6     long long  x1,y1,x0,y0;
 7     x0=1; y0=0;
 8     x1=0; y1=1;
 9     x=0; y=1;
10     long long  r=m%n;
11     long long  q=(m-r)/n;
12     while(r)
13     {
14         x=x0-q*x1; y=y0-q*y1;
15         x0=x1; y0=y1;
16         x1=x; y1=y;
17         m=n; n=r; r=m%n;
18         q=(m-r)/n;
19     }
20     return n;
21 }
22 int main()
23 {
24     long long a,b,c,x,y;
25     cin>>c>>a>>b;
26     long long g = exgcd(a,b,x,y);
27     if(c%g) cout<<"NO"<<endl;
28     else{
29         
30         x*=c/g;
31         y*=c/g;
32         while(x<0) x+=b/g,y-=a/g;
33         while(y<0) y+=a/g,x-=b/g;
34         if(x<0 || y<0) 
35         {
36             cout<<"NO"<<endl;
37             return 0;
38         }
39         cout<<"YES"<<endl;
40         cout<<x<<" "<<y<<endl;
41     }
42 }

拓展歐幾裏得算法