扩展欧几里得算法

扩展欧几里得算法,可以在计算gcd(a,b)的同时,计算出

ax+by=gcd(a,b)中a、b的值

#include<stdio.h>
#include<iostream>
using namespace std;

long long ext_gcd(long long a, long long b, long long *x, long long *y)
{
if(b==0)
{
*x = 1,*y = 0;
return a;
}
else
{
long long r = ext_gcd(b, a%b, x, y);
long long t = *x;
*x = *y;
*y = t - a/b * *y;
return r;
}
}

int ext_gcd(int a, int b, int *x, int *y)
 {
     if(b==0)
     {
         *x = 1,*y = 0;
         return a;
     }
     else
     {
         int r = ext_gcd(b, a%b, x, y);
         int t = *x;
         *x = *y;
         *y = t - a/b * *y;
         return r;
     }
 }
int main()
{
    int a,b;
    int x,y;
    while(1)
    {
        cin>>a>>b;
        cout<<"ext_gcd:"<<ext_gcd(a,b,&x,&y)<<endl;
        cout<<"ax+by=gcd(x,y)==>x y :"<<x<<"  "<<y<<endl;
        cout<<"y*b:"<<y*b<<"  y*b % a: "<<(y*b)%a<<"  [(y*b%a)+a]%a: "<< ((y*b%a)+a)%a<<endl;

    }
}

 在求解出x,y之后,(x+b/gcd, y-a/gcd)都是可行的解。

通过ext_gcd,我们还可以求满足以下条件的方程的解:

a+cx%2^k=b,求解最小的x
a-b+cx%2^k=0
cx=(b-a)%2^k·························@1:典型的同余方程,通过ext_gcd求解
cx+(2^k)y=(b-a)
当且仅当 gcd(c,2^k)|(b-a)时,方程有解。
我们通过ext_gcd求得 cx+(2^k)y=gcd(b-a)的解 x,y,gcd.
把方程的两边同时/gcd*(b-a)即得到 @1式的解。
即 x = x*(b-a)/gcd。
因为我们要求最小的x,所以我们求出符合条件的x的变化周期:T:= (2^k)/gcd.
然后通过(x%T+T)%T得到最小的x,别问我为什么,因为我也不知道为什么。
原文地址:https://www.cnblogs.com/superxuezhazha/p/5760395.html