zoukankan      html  css  js  c++  java
  • sss

    <更新提示>

    <第一次更新>


    <正文>

    乘法逆元

    我们知道,由于同余的运算只定义在整数集中,而整数集不满足除法封闭,所以同余是不满足同除性的。但是,如果有涉及取模操作的计数类题目当中需要除法运算怎么办,这就需要乘法逆元了。

    定义

    若整数(b,m)互质,且(b|a),则存在一个整数(x),满足(frac{a}{b}equiv ax(mod m)),称(x)(b)在模(m)意义下的乘法逆元,即为(b^{-1}(mod m))

    通常来说,我们会使用另一种方式来表示逆元:

    [frac{a}{b}equiv ab^{-1}equiv frac{a}{b}*b*b^{-1}(mod m) ]

    故对于逆元(b^{-1}(mod m)),满足(b*b^{-1}equiv 1(mod m))

    求解

    了解了模意义下乘法逆元的定义和作用,那么我们需要知道如何求解。通常来说,我们有好几种常用的方式,如费马小定理,扩展欧几里得等,接下来我们一一详解。

    费马小定理

    (p)为质数,则对于任意整数(a),有(a^pequiv a(mod p))

    注意到著名的费马小定理和我们的逆元非常像,可以推导一下:

    [a^pequiv a(mod p) \a^{p-1}equiv 1(mod p) \a*a^{p-2}equiv 1(mod p) ]

    所以,当模数(p)为质数时,(a^{p-2})就是(a)在模(p)意义下的乘法逆元。

    (a^{p-2})显然是可以用快速幂算的,那么我们就得到了逆元的第一种解决方案,可以求解单独一个数的逆元,时间复杂度为(O(log_2p))

    (Code:)

    inline long long power(long long a,long long b,long long p)
    {
        long long res=1;
        while (b)
        {
            if (1&b)res=res*a%p;
            a=a*a%p;
            b>>=1;
        }
        return res;
    }
    inline long long Fermat(long long a,long long p)
    {
        return power(a,p-2,p);
    }
    

    欧拉定理

    若正整数(a,p)互质,则(a^{ϕ(p)}≡1(mod p))(ϕ(p))为欧拉函数。

    费马小定理求逆元的话是要求模数(p)为质数的,更一般地,如果只能保证(a,p)互质,那么我们可以用欧拉定理求逆元。

    [a^{phi(p)}equiv 1(mod p) \a*a^{phi(p)-1}equiv 1(mod p) ]

    那么(a^{phi(p)-1})就是(a)在模(p)意义下的一个乘法逆元。

    欧拉函数可以用试除法分解质因数求,那么这就是求解逆元的第二种方法,可以求解单独一个数的逆元,时间复杂度(O(sqrt p+log_2p))

    (Code:)

    inline long long power(long long a,long long b,long long p)
    {
        long long res=1;
        while (b)
        {
            if (1&b)res=res*a%p;
            a=a*a%p;
            b>>=1;
        }
        return res;
    }
    inline long long phi(long long x)
    {
        long long ans=x;
        for (long long i=2;i*i<=x;i++)
        {
            if (x%i==0)
            {
                ans=ans/i*(i-1);
                while (x%i==0)x/=i;
            }
        }
        if (x>1)ans=ans/x*(x-1);
        return ans;
    }
    inline long long Eular(long long a,long long p)
    {
        return power(a,phi(p)-1,p);
    }
    

    线性同余方程

    我们已经知道了只有(a,p)互质时逆元(a^{-1})的求法,但是试除法求解欧拉函数未免有点慢。考虑到我们已经得到了逆元的表达方式,其实我们可以直接通过解线性同余方程的方法入手,求解逆元。

    已知逆元(a^{-1}(mod p))满足(a*a^{-1}equiv 1(mod p)),令(x=a^{-1}),则(axequiv 1(mod p))

    这是一个简单的线性同余方程,设(-py=ax-1),则可以将方程改写为(ax+py=1),利用扩展欧几里得算法找到解。

    这就是求解逆元的第三种方法,以求解单独一个数的逆元,时间复杂度(O(log_2a+log_2p))

    (Code:)

    inline long long Exeuclid(long long a,long long &x,long long b,long long &y,long long c)
    {
        if (!b){x=c/a,y=0;return a;}
        else
        {
            long long p=Exeuclid(b,x,a%b,y,c);
            long long x_=x,y_=y;
            x=y_,y=x_-a/b*y_;
            return p;
        }
    }
    inline long long Euclid(long long a,long long p)
    {
        long long x_,y_;
        Exeuclid(a,x_,p,y_,1);
        return (x_+p)%p;
    }
    

    逆元递推

    如果求的是单独一个数的逆元的话,那么以上的算法基本上可以完美解决了。现在,如果需要快速的求解(1-n)每一个数模(p)意义下的逆元,我们就需要要到逆元递推了。

    引理:(x^{-1}=(p-frac{p}{x})*(p mod x)^{-1} mod p)

    证明:

    (t=lfloor frac{p}{x} floor)(k=p mod x),即(p=tx+k)

    那么显然有(tx+kequiv 0(mod p)),则(-txequiv k(mod p))

    将上式两边同时除以(x*k),则(-t*k^{-1}equiv x^{-1}(mod p)),进而得到(x^{-1}=(p-frac{p}{x})*(p mod x)^{-1} mod p)

    已知(1^{-1}=1),那么剩下的递推就行了,可以求解(1-n)所有数的逆元,时间复杂度(O(n))

    (Code:)

    inline long long recursion(int n)
    {
        inv[1]=1;
        for (int i=2;i<=n;i++)
            inv[i]=(p-p/i)*inv[p%i]%p;
    }
    

    逆元递归

    当然,利用上述引理,我们也可以直接递归来求解单独一个数的逆元,时间复杂度为(O(log_2a))

    (Code:)

    inline long long inv(long long x,long long p)
    {
        if (x==1)return 1;
        else return (p-p/x)*inv(p%x)%p;
    }
    

    总结

    至此,本文已经介绍了(5)种求乘法逆元的方案,其中每一种方法都有各自的优缺点,希望读者能够灵活运用,选择合适的方法来求解逆元。


    <后记>

  • 相关阅读:
    环境是如何建立的 启动文件有什么
    环境中存储的是什么
    串行 并行 异步 同步
    TPC-H is a Decision Support Benchmark
    进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道
    删除环境变量
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
  • 原文地址:https://www.cnblogs.com/Parsnip/p/10698402.html
Copyright © 2011-2022 走看看