扩展欧几里得定理小理解

扩展欧几里得是伟大的人类智慧
参考了yoer77文件!!!!
扩展欧几里得定理是OI中经常出现的数论知识。

1.用来解决与线性不定方程的问题

他可以神奇的用来求解二元一次不定方程
形如a*x+b*y=c(a,b均不为0)的方程,a,b,c都是整数,求(x,y)的整数解。
判断是否有解二元一次方程是否存在整数解
扩展欧几里得算法就是在求 a,b 的最大公约数 m=gcd(a,b) 的同时,求出贝祖等式ax + by = m的一个解 (x,y)。
注意此时所解的只是m=gcd(a,b)的情况
整数二元一次不定方程有解的充分必要是gcd(a,b)|c。如果不能整除则无解。
求解整数解
这是扩展欧几里得最难理解也是最精华的部分
贴一份代码

LL exgcd(LL a,LL b,int &xx,int &yy)
{
    if(b==0)
    {
        xx=1;yy=0;
        return a;
    }
    LL r=gcd(b,a%b,xx,yy);
    int t=xx;
    xx=yy;
    yy=t-(a/b)*yy;
    return r;
}

我简单谈下我的理解
1.递归求解
什么叫做疯狂递归求解

用类似辗转相除法,求二元一次不定方程47x+30y=1的整数解。
47=30*1+17
30=17*1+13
17=13*1+4
13=4*3+1
然后把它们改写成“余数等于”的形式
17=47*1+30*(-1) //式1
13=30*1+17*(-1) //式2
4=17*1+13*(-1) //式3
1=13*1+4*(-3)
然后把它们“倒回去”
1=13*1+4*(-3) //应用式3
1=13*1+[17*1+13*(-1)]*(-3)
1=13*4+17*(-3) //应用式2
1=[30*1+17*(-1)]4+17(-3)
1=30*4+17*(-7) //应用式1
1=30*4+[47*1+30*(-1)]*(-7)
1=30*11+47*(-7)
得解x=-7, y=11。

 用一个方便我自己理解的方式,把求解的过程写出来好了。这里的大括号"{}"里面不是函数体,"{"表示一层递归调用的开始,"}"表示该层递归的结束。 
 exgcd(47, 30, x, y)
 {
     r = exgcd(30, 17,x, y)
     {
         r = exgcd(17, 13, x, y)
         {
             r = exgcd(13, 4, x, y)
             {
                 r = exgcd(4, 1, x, y)
                 {
                     r = exgcd(1, 0, x, y)
                     {
                         x = 1; 
                         y = 0;
                         return 1;
                     }
                     t = y = 0;
                     y = x - (4/1) * y = 1;
                     x = t = 0;
                     return r = 1; 
                 }
                 t = 1;
                 y = 0 - (13/4) * 1 = -3;
                 x = 1;
                 return 1;
             }
             t = -3;
             y = 1 - (17/13) * (-3) = 4;
             x = -3;
             return 1;
         }
         t = 4;
         y = -3 - (30/17) * 4 = -7;
         x = 4;
         return 1;
     }
     t = -7;
     y = 4 - (47/30) * (-7) = 11;
     x = -7;
     return 1;
 }
 最后的结果:
 r = exgcd(47,30,x,y) = 1;
 x = -7;
 y = 11;

这就可以非常好的理解这个伟大人类智慧
那么r就是最大公约数
x和y就是两个可以是不定方程满足的通解
所以说对于不同的题目我们还要进行不同的对于所得x和y的处理。

2.乘法逆元

乘法的逆元这里只讲用扩展欧几里得的求法
因为根据逆元的定义ax≡1(mod p)且a和p互质
这里求解x就相当于是求gcd(a,p)=1的扩展欧几里得的情况啊这还是相当简单惬意的

#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL n,q,x,y;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1;y=0;
        return a;
    }
    LL r=exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-(a/b)*y;
    return r;
}
int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        exgcd(i,q,x,y);
        while(x<0) x+=q;
        printf("%d\n",x);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值