【扩展欧几里得算法】(瞎几把乱搞式)

扩展欧几里得算法;

补充两个常识(2333333)

【某定理】:计算两个正整数的最大公因子时,所需的除法次数不会超过较小的那个数的10进制的5倍;

【补充】:a和b 互素的条件,gcd(a,b)=1;  存在整数x,y,使得xa+yb=1.

 

 

= =以下绝大部分是结果/定理= =【T^T搞得我累死了,想看讲解的请关闭并点击【详解】】

利用扩展GCD求解一个不定方程。

定义:   gcd=Gcd(a,b)=xa+yb;

我们有一个不定方程:a*x + b*y = gcd   (有解),

 

我们可以找出一个通解,

 

x= x0 + (b/gcd)*t

y = y0-(a/gcd)*t

 

我们是否可以从最终状态反推到最初的状态呢?

 

两个相邻的状态之间:

       gcd = b*x1 + (a-(a/b)*b)*y1     //a%b = a- (a/b)*b

         = b*x1 + a*y1 – (a/b)*b*y1

          = a*y1 + b*(x1 – a/b*y1)


所以--代码:【强行知道是这么回事】

int exgcd(inta,int b,int &x,int &y)

{

    if(b==0)

    {

        x=1;

        y=0;

        return a;

    }

    int ans=exgcd(b,a%b,&x,&y);

    int temp=x;

    x=y;

    y=temp-a/b*y;

    return ans;

}

 

想要练习一波  求解一个不定方程的(两题都是裸的):

ZOJ  3609http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4712

HDU2669   http://acm.hdu.edu.cn/showproblem.php?pid=2669

 

int exgcd(inta,int b,int &x,int &y)

{

    if(b==0)

    {

        x=1;

        y=0;

        return a;

    }

    int ans=exgcd(b,a%b,x,y);

    int temp=x;

    x=y;

    y=temp-a/b*y;

    return ans;

}

int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        int x,y;

        int a,m;

        scanf("%d%d",&a,&m);

        if(exgcd(a,m,x,y)==1)

        {

//            printf("x=%d\n",x);

//            printf("y=%d\n",y);

            if(x<=0)

            {

                x+=m;

            }

            cout<<x<<endl;

            //算法中的通解x0可以理解成最小的x(如果有些问题到最大是不是ax,by互换一下(by+ax=1)就好了呢?23333)

            //由于问题的特殊性,有时候我们得到的特解 x0 是一个负数

        }

        else

            printf("Not Exist\n");

    }

    return 0;

}

 

你可能感兴趣的:(数论,扩展欧几里得算法)