zoukankan      html  css  js  c++  java
  • 乘法逆元模板

    1.扩展欧几里得求逆元

    typedef long long ll;
    
    //ax + by = gcd(a,b)
    //传入固定值a,b.放回 d=gcd(a,b), x , y
    void extendgcd(ll a,ll b,ll &d,ll &x,ll &y)
    {
        if(b==0){d=a;x=1;y=0;return;}
        extendgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
    
    //Ax=1(mod M),gcd(A,M)==1
    //输入:10^18>=A,M>=1
    //输出:返回x的范围是[1,M-1]
    ll GetNi(ll A,ll M)
    {
        ll rex=0,rey=0;
        ll td=0;
        extendgcd(A,M,td,rex,rey);
        return (rex%M+M)%M;
    }

    2.根据欧拉定理求逆元,当mod素数时可以速度较快。

    //a^b%mod 快速幂
    long long Quk_Mul(long long a,long long b,long long mod)
    {
        long long qsum=1;
        while(b)
        {
            if(b&1) qsum=(qsum*a)%mod;
            b>>=1;
            a=(a*a)%mod;
        }
        return qsum;
    }
    
    //欧拉函数:复杂度O(n^(0.5)),返回[1,n-1]中所有和n互素的数的个数和
    ll phi(ll x)
    {
        ll sum=x;
        for(ll i=2;i*i<=x;i++)
        {
            if(x%i==0)
            {
                sum=sum-sum/i;
                while(x%i==0) x/=i;
            }
        }
        if(x!=1) sum=sum-sum/x;
        return sum;
    }
    
    //Ax=1(mod M),gcd(A,M)==1
    //输入:10^18>=A,M>=1
    //输出:返回x的范围是[1,M-1]
    //复杂度:如果M是素数,则直接用M-2代替phi(M)-1 复杂度为O(logM)
    //       如果M不是素数,则复杂度为O( M^(0.5) ) 好慢。
    ll GetNi(ll A,ll M)
    {
        //return Quk_Mul(A, phi(M)-1, M);
        return Quk_Mul(A, M-2, M);
    }

    3.对于a/b (mod m),不要求b和m互质。前提当然b能整除a

    (a/b) % m等于a%(b*m)/b

    只要是bm不需要高精度,这种方法是很好用的。

    证明还是很好证的:

    (a/b) mod m = a/b – k*m = (a – k*b*m)/b =(a%(b*m))/b;

  • 相关阅读:
    巨蟒python全栈开发-第3天
    python全栈开发-第1天
    2018.11.23-day28 异常处理&hashlib
    面试题1
    if __name__ == "__main__": 怎么理解?
    2018.11.23-day27 面向对象(大总结)
    2018.11.23-day26 面向对象(终结)
    20181125 test
    (39.1) Spring Boot Shiro权限管理【从零开始学Spring Boot】
    Android一键换肤功能:一种简单的实现
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5034531.html
Copyright © 2011-2022 走看看