费小或者扩展欧几里得求逆元

什么是逆元
所谓逆元是指对于一个二元运算∗∗的集合而言,如果ee是运算的单位远,那么a∗x=ea∗x=e,就称xx是aa的逆元,比如对于加法而言,逆元就是0,对于乘法而言,逆元就是1。
现在这里讨论的是同余关系中的逆元,即ax≡1(modm)ax≡1(modm),对于给定的aa,求解xx。

如何求解
方程ax≡1(modm)ax≡1(modm)其实等同与方程ax−my=gcd(a,m)ax−my=gcd(a,m),如此,便可以通过扩展欧几里得求解逆元,同时,这个方法指出有解的前提是aa与mm互质。

欧拉定理:
如果gcd(a,m)=1.
这里写图片描述
费马小定理;
如果g(a,p)=1 且p是素数的话
因为euler(p)==p-1,由欧拉定理得:
这里写图片描述

贴上模板代码:

#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long ll;

ll extendGcd(ll a,ll b,ll &x,ll &y){
    ll ans,t;
    if(b==0){
        x=1;y=0;
        return a;
    }
    ans=extendGcd(b,a%b,x,y);
    t=x;x=y;y=t-(a/b)*y;
    return ans;
}
//返回x,a*x=1(mod m)
ll getInv(ll a,ll m){
    ll x,y,d;
    d=extendGcd(a,m,x,y);
    if(d==1)
        return (x%m+m)%m;
    else
        return -1;
}
long long euler(long long x)
{
    long long res=x;
    for(long long i=2;i<(int)sqrt(x*1.0)+1;i++)
        if(x%i==0)
        {
            res=res/i*(i-1);
            while(x%i==0)
                x/=i;
        }
    if(x>1)
        res=res/x*(x-1);
    return res;
}
//如果m是1000000007这样的素数用费小求逆元
long long quickpowmod(long long x, long long y, long long mod)
{
      long long ret = 1;
      while(y){
         if(y&1)
             ret = ret*x%mod;
         x = x*x%mod;
         y >>= 1;
     }
     return ret;
 }


int main()
{
    ll a,m;
    while(cin>>a>>m){
        cout<//m不是素数
        cout<2,m)<//m是素数
    }

    return 0;
}

你可能感兴趣的:(费小或者扩展欧几里得求逆元)