除法求逆元(扩展欧几里德和费马小定理)

我们都知道除法不满足取模,那么我们可以求模的逆元来进行求结果,既然乘法可以取模,如果这个数除以一个数,那么我们可以让他乘以一个数使得和除以那个数的结果相同,那么乘的这个数就是那个数的乘法逆元。下面摘自Acdreamer的博客

今天我们来探讨逆元在ACM-ICPC竞赛中的应用,逆元是一个很重要的概念,必须学会使用它。

 

对于正整数,如果有,那么把这个同余方程中的最小正整数解叫做的逆元。

 

逆元一般用扩展欧几里得算法来求得,如果为素数,那么还可以根据费马小定理得到逆元为

 

推导过程如下

求现在来看一个逆元最常见问题,求如下表达式的值(已知

 

           

 

当然这个经典的问题有很多方法,最常见的就是扩展欧几里得,如果是素数,还可以用费马小定理。

 

但是你会发现费马小定理和扩展欧几里得算法求逆元是有局限性的,它们都会要求互素。实际上我们还有一

种通用的求逆元方法,适合所有情况。公式如下

 

         

 

现在我们来证明它,已知,证明步骤如下

 

         

 

 

 

 

下面是两个求乘法逆元的模板

辗转相除法求逆元(求a对于mod的逆元, 要求a与mod互素)

 

ll exgcd(ll a, ll b, ll &x, ll &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll r = exgcd(b, a % b, x, y);
    ll t = x % mod;
    x = y % mod;
    y = ((t - a / b * y) % mod + mod) % mod;
    return r;
}

求2对于1e9+7的逆元就是 exgcd(2, 1e9+7, x, y),其中x的值就是inv2,

 

费马小定理求逆元(求a对于mod的逆元,要求mod为素数)

ll power_mod(ll a, ll b, ll mod)
{
    ll ans = 1;
    while (b)
    {
        if (b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
inv2 = power_mod(a, mod - 2, mod);

 

posted @ 2015-11-03 11:03  Howe_Young  阅读(7182)  评论(0编辑  收藏  举报