• 乘法逆元


    1、什么是逆元

    当求解公式:(a/b)%m 时,因b可能会过大,会出现爆精度的情况,所以需变除法为乘法:

    设c是b的逆元,则有b*c≡1(mod m);

    则(a/b)%m = (a/b)*1%m = (a/b)*b*c%m = a*c(mod m);

    即a/b的模等于a*b的逆元的模;

     

     

    2、求逆元的几种方法

    (1).费马小定理

    在p是素数的情况下,对任意整数x都有x^p≡x(mod)p。 
    如果x无法被p整除,则有x^(p−1)≡1(modp) 。 
    可以在p为素数的情况下求出一个数的逆元,x∗x^(p−2)≡1(modp) ,x^(p−2)即为逆元。

    程序代码:

    const int mod = 1000000009;  
    long long quickpow(long long a, long long b) {  
        if (b < 0) return 0;  
        long long ret = 1;  
        a %= mod;  
        while(b) {  
            if (b & 1) ret = (ret * a) % mod;  
            b >>= 1;  
            a = (a * a) % mod;  
        }  
        return ret;  
    }  
    long long inv(long long a) {  
        return quickpow(a, mod - 2);  
    }  
    
    
     

    (2).扩展欧几里得算法求逆元

    扩展欧几里得算法可以参考小白书;

    百度百科-乘法逆元中有这样一个例子:

    例如:4关于1模7的乘法逆元为多少?
    4X≡1 mod 7
    这个方程等价于求一个X和K,满足
    4X=7K+1
    其中X和K都是整数。

    求x,k就是扩展欧几里得算法了吧~

    可扩展欧几里得求逆元ax≡1(mod n)其中a,n互质;

    复杂度:O(logn);

    ll extend_gcd(ll a, ll b, ll &x, ll &y)
    {
        if (b == 0)
        {
            x = 1, y = 0;
            return a;
        }
        else
        {
            ll r = extend_gcd(b, a % b, y, x);
            y -= x * (a / b);
            return r;
        }
    }
    ll inv(ll a, ll n)
    {
        ll x, y;
        extend_gcd(a, n, x, y);
        x = (x % n + n) % n;
        return x;
    }

    (3).递推法求逆元

    证明:

    设x = p % a,y = p / a
    于是有 x + y * a = p
    (x + y * a) % p = 0
    移项得 x % p = (-y) * a % p
    x * inv(a) % p = (-y) % p
    inv(a) = (p – y) * inv(x) % p
    于是 inv(a) = (p – p / a) * inv(p % a) % p

    然后一直递归到1为止,因为1的逆元就是1

    代码:

    const int mod = 1000000009;
    ll inv(ll a)   
    {  
        return a == 1 ? 1 : (mod - mod / a) * inv(mod % a, mod) % mod;  
    }
    宝剑锋从磨砺出 梅花香自苦寒来
  • 相关阅读:
    K3Wise K3List.OCX引入dotnet问题处理方法
    k3wise dotnet开发老单据时序簿工具条添加按钮
    c#调用dotnet写的com组件碰到注册失败的错误的补救方法
    bat注册dotnet com
    dotnet动态加载以及卸载dll的代码
    c#获取com对象的progid
    jpg和png的区别
    Fragment的FragmentTransaction 的commit()和commitAllowingStateLoss()以及commitNow()和commitNowAllowingStateLoss()
    Java泛型类型擦除与运行时类型获取
    rxjava介绍
  • 原文地址:https://www.cnblogs.com/GHzcx/p/8576744.html
Copyright © 2020-2023  润新知