欧几里德再现(模板-不完全转载!)

本文借鉴于 :http://blog.csdn.net/u013451221/article/details/38497029

内容略微不同。

1.1.欧几里得(最大公约数,最小公倍数)

int gcd(int a,int b)
{
    if((b==0)   return a;
    else   gcd(b,a%b);       
}

2扩展欧几里德求最小整数解;

给出 a*x+b*y=c

void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if (!b)
    {
        d=a;
        x=1;
        y=0;
    }
    else 
    {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}

代码求解的是a*x+b*y=gcd(a,b);

if(c%gcd(a,b)==0)  说明有解;

且最小整数解为 b=b/gcd(a,b);x=x*(c/gcd(a,b));x=(x%b+b)%b;

3.最小乘法逆元

类似于求最小正整数解,只不过最后要 a*x+b*y=1;

什么是乘法逆元:

例如:4关于 1模7的乘法逆元为多少?

4x = 1 mod 7;

此方程等价于求解:

4x=7k+1;

其中x和K都是整数。

若ax=1 mod f,则称a关于模f的乘法逆元为x,可表示为 ax=1(mod f);

int cal(int a,int m)
{
    int x,y;
    int gcd=e_gcd(a,m,x,y);
    if(1%gcd!=0) return -1;
    x*=1/gcd;
    m=abs(m);
    int ans=x%m;
    if(ans<=0) ans+=m;
    return ans;
}
原文地址:https://www.cnblogs.com/SunQi-lvbu/p/7085836.html