扩展欧几里得算法 以及求逆元的几种方法


扩展欧几里得算法:

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