• 欧几里得算法和拓展欧几里得


        1:欧几里得算法,既辗转相除法。用于计算正整数a,b的最大公约数。举个例子,简单明了:

         12/8==1.....4

         8/4==2......0

         4/0==0 ,除数为0,终止,被除数为答案:4

           除数和余数反复做%运算,其实和/没什么关系了,直接看%就可以了,所以有递归代码:

    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }

          最小公倍数求解:a,b的最小公倍数等于a,b的乘积除以a,b的最大公约数:

    cout<<x/gcd(x,y)*y<<endl;

         2:拓展欧几里得算法:参考自:https://blog.csdn.net/destiny1507/article/details/81750874,感谢大佬!

          首先有贝祖定理:a,b为整数,那么一定存在x,y使得a*x+b*y==gcd(a,b)。也可以说,a*x+b*y==m,那么m一定是gcd(a,b)的若干倍,可以用来判断方程是否有解。如何求x,y?这就是拓展欧几里得可以解决的一个问题了。

          如果辗转相除法到达了最底层:即a%b==0,此时a*x+b*y==gcd(a,b),x==1,y==0。此时的a,b已经不是初始的a,b了,要想得到初始a,b的x,y,需要递归到最底层再一层层往上推各个层次的x,y,直到第一层。递归算法中,是先得到下一个状态值。

          所以算a,b的x,y,假设下一层b,a%b得到了gcd,这个下一层是满足:b*x1+a%b*y1==gcd。对于a%b,有:a%b=a-(a/b)*b。所以原式为:

          b*x1+(a-a/b*b)*y1=a*y1+b*(x1-a/b*y1)。

          所以:x==y1,y==(x1-a/b*y1)。y1,x1均来源于下一层,所以通过递归先得到下一层,然后根据式子推出当前一层,直到得到原a,b的x,y来。

    ll x,y,a,b;
    void exgcd(ll a, ll b)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return ;
        }
        exgcd(b,a%b);
        ll t=x;
        x=y;
        y=t-a/b*y;
        return ;
    }
  • 相关阅读:
    【转】js 获取浏览器高度和宽度值(多浏览器)
    Css相册
    微信公众号开发笔记2-自定义菜单
    微信公众号开发笔记1-获取Access Token
    【转】CSS选择器笔记
    【转】CSS浮动(float,clear)通俗讲解
    高云的jQuery源码分析笔记
    经典闭包例子详解
    执行控制——节流模式
    图片上下左右的无缝滚动的实现
  • 原文地址:https://www.cnblogs.com/liyexin/p/12798101.html
Copyright © 2020-2023  润新知