求解同余方程 数论 扩展欧几里得

本文介绍了扩展欧几里得算法及其在解决不定方程a⋅x+b⋅y=1中的应用,同时阐述了裴蜀定理,说明了如何找到该方程的一组解及所有解的通式。通过示例代码展示了如何利用扩展欧几里得算法求解整数解,并给出了一种边界情况和一般情况的解法。

题面:
在这里插入图片描述
在这里插入图片描述
思路:
a⋅x=b⋅y+1a⋅x−b⋅y=1因为y的取值是任意的,因此可以将这个式子看成:a⋅x+b⋅y=1因为题目保证有解,所以a和b是互质的,即gcd⁡(a,b)=1而扩展欧几里得就是用来求形如:a⋅x+b⋅=c的不定方程的整数解的这里需要再补充一个裴蜀定理:若a,b为整数,那么一定存在a⋅x+b⋅y=gcd⁡(a,b)即a⋅x+b⋅y的值一定是gcd⁡(a,b)的倍数先考虑边界情况a⋅1+b⋅0=gcd⁡(a,b),此时,x=1,y=0然后考虑一般情况,假设某一次得到的解是x0、y0b⋅x0+(a mod b)⋅y0=gcd⁡(a,b)b⋅x0+(a−⌊ab⌋⋅b)⋅y0=gcd⁡(a,b)a⋅y0+b⋅(x0−⌊ab⌋⋅y0)=gcd⁡(a,b)由此可得:x=y0,y=x0−⌊ab⌋⋅y0已知任意一组解x0,y0通解为:x=x0+bgcd⁡(a,b)⋅nx=x0+bgcd⁡(a,b)⋅n a\cdot x=b\cdot y +1\\ a\cdot x-b\cdot y =1\\ \text{因为y的取值是任意的,因此可以将这个式子看成:}\\ a\cdot x+b\cdot y =1\\ \text{因为题目保证有解,所以a和b是互质的,即}\gcd(a,b)=1\\ \text{而扩展欧几里得就是用来求形如:} a\cdot x+b\cdot=c\text {的不定方程的整数解的}\\ \text{这里需要再补充一个裴蜀定理:}\\ \text{若}a,b\text{为整数,那么一定存在}a\cdot x+b\cdot y=\gcd(a,b)\\ \text{即}a\cdot x+b\cdot y \text{的值一定是}\gcd(a,b)\text{的倍数}\\ \text{先考虑边界情况}a\cdot 1+b\cdot 0=\gcd(a,b),\text{此时,}x=1,y=0\\ \text{然后考虑一般情况,假设某一次得到的解是}x_0、y_0\\ b\cdot x_0+(a\bmod b)\cdot y_0=\gcd(a,b)\\ b\cdot x_0+(a-\lfloor \frac a b \rfloor\cdot b)\cdot y_0=\gcd(a,b)\\ a\cdot y_0+b\cdot (x_0-\lfloor \frac a b \rfloor\cdot y_0)=\gcd(a,b)\\ \text{由此可得:} x=y_0 ,y=x_0-\lfloor \frac a b \rfloor\cdot y_0\\ \text{已知任意一组解}x_0,y_0\text{通解为:} \\ x=x0+ \frac{b} {\gcd (a,b)}\cdot n\\ x=x0+ \frac{b} {\gcd (a,b)}\cdot n\\ ax=by+1axby=1因为y的取值是任意的,因此可以将这个式子看成:ax+by=1因为题目保证有解,所以ab是互质的,即gcd(a,b)=1而扩展欧几里得就是用来求形如:ax+b=c的不定方程的整数解的这里需要再补充一个裴蜀定理:a,b为整数,那么一定存在ax+by=gcd(a,b)ax+by的值一定是gcd(a,b)的倍数先考虑边界情况a1+b0=gcd(a,b),此时,x=1,y=0然后考虑一般情况,假设某一次得到的解是x0y0bx0+(amodb)y0=gcd(a,b)bx0+(abab)y0=gcd(a,b)ay0+b(x0bay0)=gcd(a,b)由此可得:x=y0,y=x0bay0已知任意一组解x0,y0通解为:x=x0+gcd(a,b)bnx=x0+gcd(a,b)bn
代码:

#include <bits/stdc++.h>
#include <iostream>
using namespace std;
const int maxn=111111;
int a,b,x,y;

void exgcd(int a,int b,int *x,int *y)//扩展欧几里得算法
{
    //cout<<"a="<<a<<" "<<"b="<<b<<" "<<"x="<<*x<<" "<<"y="<<*y<<endl;
    if(b==0)
    {
        *x=1,*y=0;
        return;
    }
    exgcd(b,a%b,x,y); //r=GCD(a,b)=GCD(b, a%b)
    //cout<<"!!!a="<<a<<" "<<"b="<<b<<" "<<"x="<<*x<<" "<<"y="<<*y<<endl;
    int t=*x;
    *x=*y;
    *y=t-a/b*(*y) ;
    
}

int main()
{
    cin>>a>>b;
    exgcd(a,b,&x,&y);
    //cout<<"x="<<x<<" "<<"b="<<b<<endl;
    while(x<0) x+=b;
    cout<<x<<endl;
	return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值