学习笔记:扩展欧几里得

扩展欧几里得

问:如何求得一组 x , y x,y x,y,使得 A x + B y = C Ax+By=C Ax+By=C成立。

假设上式成立,首先令 g = g c d ( A , B ) g=gcd(A,B) g=gcd(A,B),那么上式就可以写成 k 1 g x + k 2 g y = C k_1gx+k_2gy=C k1gx+k2gy=C,化简得, g ( k 1 x + k 2 y ) = C g(k_1x+k_2y)=C g(k1x+k2y)=C,说明 C % g C\%g C%g=0 。所以 A x + B y = C Ax+By=C Ax+By=C存在解得条件就是 C % g C\%g C%g=0;反之,则不存在。

根据数论中相关定理,存在x,y,满足: A x + B y = g c d ( A , B ) Ax+By=gcd(A,B) Ax+By=gcd(A,B)
怎么求一组解呢?
A x 1 + B y 1 = g c d ( A , B ) Ax_1+By_1=gcd(A,B) Ax1+By1=gcd(A,B)·················································································1
B x 2 + ( A % B ) y 2 = g c d ( B , A % B ) Bx_2+(A\%B)y_2=gcd(B,A\%B) Bx2+(A%B)y2=gcd(B,A%B)
B x 2 + ( A − ( A / B ) ∗ B ) y 2 = g c d ( B , A % B ) Bx_2+(A-(A/B)*B)y_2=gcd(B,A\%B) Bx2+(A(A/B)B)y2=gcd(B,A%B)····················································2
1,2式等式左边相等: A x 1 + B y 1 = B x 2 + ( A − ( A / B ) ∗ B ) y 2 Ax_1+By_1=Bx_2+(A-(A/B)*B)y_2 Ax1+By1=Bx2+(A(A/B)B)y2
整理一下: A x 1 + B y 1 = A y 2 + B ( x 2 − ( A / B ) y 2 ) Ax_1+By_1=Ay_2+B(x_2-(A/B)y_2) Ax1+By1=Ay2+B(x2(A/B)y2)

可以很明显看出: x 1 = y 2 , y 1 = x 2 − ( A / B ) y 2 x_1=y_2,y_1=x_2-(A/B)y_2 x1=y2,y1=x2(A/B)y2。下面给出代码

long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if(b==0){
        x=1,y=0;//如果b==0,那么gcd(A,B)=A,那么x=1,y=0
        return a;
    }
    long long ans=exgcd(b,a%b,x,y);
    int temp=x;//下面这三句之所以要放在递归调用和return之间是因为要根据后面递归算出来的x,y值才能推出最开始的x,y
    x=y;//(接上一行注释)也就是Ax+By=gcd(A,B)的解
    y=temp-(a/b)*y;
    return ans;
}

执行完这段程序后就可以得到一组特解x,y。那么怎么求通解呢,下面给出证明:
在这里插入图片描述通解: x = x 0 + B g c d ( A , B ) ∗ t x=x_0+\frac{B}{gcd(A,B)}*t x=x0+gcd(A,B)Bt
y = y 0 − A g c d ( A , B ) ∗ t y=y_0-\frac{A}{gcd(A,B)}*t y=y0gcd(A,B)At
t为整数
就写道这吧。以后发现不足再改。

例题:
A line on the plane is described by an equation Ax + By + C = 0. You are to find any point on this line, whose coordinates are integer numbers from  - 5·1018 to 5·1018 inclusive, or to find out that such points do not exist.
Input

The first line contains three integers A, B and C ( - 2·109 ≤ A, B, C ≤ 2·109) — corresponding coefficients of the line equation. It is guaranteed that A2 + B2 > 0.
Output

If the required point exists, output its coordinates, otherwise output -1.

Examples

Input

2 5 3

Output

6 -3
模板扩展欧几里得题:
在这里插入图片描述代码:

#include<cstdio>
#include<set>
#include<map>
#include<string.h>
#include<string>
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
typedef long long LL;
using namespace std;
const int maxn=1e6+5;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0){
        x=1,y=0;
        return a;
    }
    LL ans=exgcd(b,a%b,x,y);
    LL temp=x;
    x=y;
    y=temp-(a/b)*y;
    return ans;
}
int main()
{
    LL a,b,c,x,y;
    scanf("%lld%lld%lld",&a,&b,&c);
    LL g=exgcd(a,b,x,y);
    if((-c)%g!=0){
        printf("-1\n");
    }
    else {
        LL ansx=x*(-c/g);
        LL ansy=y*(-c/g);
        printf("%lld %lld\n",ansx,ansy);
    }

    return 0;
}

下面再补充一点求通解和最小正整数的解的代码

#include<cstdio>
#include<set>
#include<map>
#include<string.h>
#include<string>
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
typedef long long LL;
using namespace std;
const int maxn=1e6+5;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0){
        x=1,y=0;
        return a;
    }
    LL ans=exgcd(b,a%b,x,y);
    LL temp=x;
    x=y;
    y=temp-(a/b)*y;
    return ans;
}
int main()
{
    LL a,b,c,x,y;
    scanf("%lld%lld%lld",&a,&b,&c);
    LL g=exgcd(a,b,x,y);
    if((-c)%g!=0){
        printf("-1\n");
    }
    else{
        LL ansx=x*(-c/g);
        LL ansy=y*(-c/g);
        LL ta=b/g;
        LL tb=a/g;
        for(LL i=1;i<=100;i++){//枚举许多组解的过程
            x=ansx+i*ta;
            y=ansy-i*tb;
            printf("%lld %lld\n",x,y);
            cout<<(x*a+y*b+c==0)<<endl;
        }

        x=ansx+10*ta;//假设随意一组解,求x,y的最小正整数解
        y=ansy-10*tb;
        x=(x%ta-ta)%ta;
        y=(y%tb+tb)%tb;//y的最小正整数解

        x=(x%ta+ta)%ta;//x的最小正整数解
        y=(y%tb-tb)%tb;

        printf("%lld %lld\n",x,y);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值