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;

  • 相关阅读:
    docker学习笔记及hadoop集群搭建
    Zookeeper+Kafka+Storm+HDFS实践
    zookeeper集群搭建
    scala学习笔记——特质
    scala学习笔记-集合
    scala学习笔记-隐式转换和隐式参数
    RDD 重新分区,排序 repartitionAndSortWithinPartitions
    scala学习笔记——操作符
    JAVA基础系列(一) 概述与相关概念
    网络收藏夹
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5034531.html
Copyright © 2011-2022 走看看