扩展欧几里得定律

北城以北 提交于 2019-11-30 23:21:47

扩展欧几里得所能求的东西:不定方程的某一整数解,同余方程,乘法逆元

首先了解一个性质(裴蜀定理):ax+by=c 有整数解当且仅当c为gcd(a,b)的倍数

然后是两个预备知识:gcd(a,b)=gcd(b,a%b)   a%b=a-a/b*b(此处/表示整除)


 

不定方程的解:

不妨设a>b

另ax1+by1=gcd(a,b)  bx2+(a%b)y2=gcd(b,a%b)

因为gcd(a,b)=gcd(b,a%b)

所以 ax1+by1=bx2+(a%b)y2

因为a%b=a-a/b*b

所以ax1+by1=ay2+b(x2-(a/b)*y2)

所以x1=y2 ; y1=x2-(a/b)*y2

这样就可以递归处理 显然当b=0时为边界条件

我们令当b=0时 x=1 y=0

然后慢慢回溯

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define int long long 
using namespace std;

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

signed main()
{
    int a,b,x,y,d;
    scanf("%lld %lld",&a,&b);
    d=exgcd(a,b,x,y);
    printf("%lld",(x%(b/d)+(b/d))%(b/d)); 
}

求出不定方程的最小解

emmm其实就是上面的输出。

因为x%(b/d)可能为负数 所以要加上b/d 然后再模b/d


 

同余方程

axΞp(mod b)

方程可改写为ax=by+p →ax+by=p(注意此处移项后y的系数并没有取相反数,因为y的值对这个式子没有影响)

显然当p为gcd(a,b)的倍数的时候,有整数解

然后就是emmmm不定方程的解法了


乘法逆元

首先科普一下逆元是什么意思(令a在mob p的情况下逆元的符号为inva)

a*invaΞ1(mod p)  对,这个就是乘法逆元的作用

那么如何用扩展欧几里得求乘法逆元呢

令x=inva b=p

然后就完事了     

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

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

inline int niyuan(int a,int m)
{
    int x,y;
    exgcd(a,m,x,y);
     return (x%m+m)%m;
}


int main()
{
    int n,p;
    scanf("%d %d",&n,&p);
    for(register int i=1;i<=n;i++)
    {
        printf("%d\n",niyuan(i,p));
    }
}

总结:不管是同余方程还是乘法逆元,都是将其转换为不定方程的形式,再进行扩展欧几里得的运算     

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!