擴展歐幾里得算法 以及求逆元的幾種方法


擴展歐幾里得算法:

a x + b y = g c d ( a , b ) ax+by=gcd(a,b)​ 求出滿足條件唯一的x,y的值

設:

r 0 = q 1 r 1 + r 2 r_{0}=q_{1}*r_{1}+r_{2}

r 1 = q 2 r 2 + r 3 r_{1}=q_{2}*r_{2}+r_{3}

r 2 = q 3 r 3 + r 4 r_{2}=q_{3}*r_{3}+r_{4}​

. . . . . . . . . . ..........

r k 1 = q k r k r_{k-1}=q_{k}*r_{k}​

其中 r k r_{k}​ 就是最大公約數,因為 r k r_{k}​ 可由 r k 1 r_{k-1}​ r k 2 r_{k-2}​ ,且 r n = r n 2 q n 1 r n 1 r_{n}=r_{n-2}-q_{n-1}*r_{n-1}​

r k 1 r_{k-1}​ 可表示為 r k 2 r_{k-2}​ r k 3 r_{k-3}​ 的線性組合

同理 r k 2 r_{k-2} 也可向上表示。這樣得到最大公約數之后,一直向上回溯即可找到滿足條件的x,y

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最大公約數,且得到gcd(a,b)=x*a+y*b;
{
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    ll gcd=ExGcd(b,a%b,x,y);
    ll temp,k;
    k=a/b;
    temp=x;
    x=y;
    y=temp-k*y;
    return gcd;
}

利用擴展歐幾里得求一次同余方程

形如式子 a x = c     ( m o d    m ) a*x=c\ \ \ (mod \ \ m) ,求滿足條件的x。

  • 且只有滿足 g c d ( a , m ) c gcd(a,m)|c 的時候才有解。

a x 1 + m y 1 = g c d ( a , m )         ax_{1}+my_{1}=gcd(a,m)\ \ \ \ \ \ \ ①

c 1 = c / g c d ( a , m ) c_{1}=c/gcd(a,m) ,

那么等式①兩邊同乘以 c 1 c_{1}​ 即可得到 a x 1 c 1 + m y 1 c 1 = c ax_{1}c_{1}+my_{1}*{c1}=c​

x = x 1 c 1 = x 1 c / g c d ( a , m ) x=x_{1}*c_{1}=x_{1}*c/gcd(a,m)​ x 1 x_{1}​ ( a , m ) (a,m)​ 的擴展歐幾里得公式中a的系數)

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最大公約數,且得到gcd(a,b)=x*a+y*b;
{
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    ll gcd=ExGcd(b,a%b,x,y);
    ll temp,k=a/b;
    temp=x;
    x=y;
    y=temp-k*y;
    return gcd;
}
bool IsOk;
ll calc(ll a,ll c,ll m)
{
    ll x,y;
    ll gcd=ExGcd(a,m,x,y);
    if(c%gcd!=0)
    {
        IsOk=false;
        return 0ll;
    }
    return c/gcd*x%m;
}

利用費馬小定理求逆元

補充一個 歐拉定理:

設φ(x)的x的歐拉函數值,如果有a和p互素,則有

a φ ( p ) = 1 ( m o d   p ) a^{φ(p)}=1(mod \ p)​

  • 費馬小定理條件:a,p互素,且p是素數

則: a p 1 = 1   ( m o d   q ) a^{p-1}=1\ (mod \ q)​

即: a a​ 關於 p p​ 的逆元為 a p 2 a^{p-2}​

/* 快速冪取模即可 */

利用擴展歐幾里得求逆元

前提

gcd(a,q)==1

逆元即ax+qy=1 (mod q)中的x

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最大公約數,且得到gcd(a,b)=x*a+y*b;
{
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    ll gcd=ExGcd(b,a%b,x,y);
    ll temp,k;
    k=a/b;
    temp=x;
    x=y;
    y=temp-k*y;
    return gcd;
}
ll getinv(ll a,ll m)
{
    ll x,y;
    if(ExGcd(a,m,x,y)!=1)
        return -1;//不互質 不存在逆元
    return x;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM