数论 - 多种方法求乘法逆元

求乘法逆元的5种方法

a 1 p a x 1 ( m o d   p ) x 求正整数a关于1模p的的乘法逆元,即求满足ax≡1(mod\ p)的正整数解x。


一、 ( O ( l o g P ) ) 扩展欧几里得算法(O(logP))

a x 1 ( m o d   p ) a x + p y = 1 x 将ax≡1(mod\ p)转化为解方程ax+py=1的正整数解x。

a p 前提条件:a与p互质,此时解唯一。

代码:

int exgcd(int a,int b,int &x,int &y)  //ax≡1(mod p)
{                                     //ax+py=1
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    
    int d=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    
    return d;
}

int main()
{
	int p,x,y;
    p=mod;
    for(int a=1;a<=20;a++)	//求出1~20的逆元
    {
        exgcd(a,p,x,y);
        cout<<(x+p)%p<<endl;
    }
}

( O ( l o g P ) ) 二、费马小定理(O(logP))

p 前提条件:p为质数

a p 1 1 ( m o d   p ) 则有a^{p-1}≡1(mod\ p)

a a p 2 1 ( m o d   p ) 即a·a^{p-2}≡1(mod\ p),

a p 2 a^{p-2}即逆元。通过快速幂可解。


( O ( P ) ) 三、欧拉定理求逆元(O(\sqrt{P}))

p , a p , a : 欧拉定理:若p,a为正整数,且p,a互质,则:

a ϕ ( p ) 1 ( m o d   p ) a^{\phi(p)}≡1(mod\ p)

扫描二维码关注公众号,回复: 11517276 查看本文章

p 当p为质数时,即费马小定理。

p ϕ ( p ) a ϕ ( p ) 1 因此,我们可以对p先求出欧拉函数\phi(p),再用快速幂求出乘法逆元为a^{\phi(p)-1}。

O ( p ) 可用定义求欧拉函数,时间复杂度O(\sqrt{p})

代码:

ll get_euler(ll C)      //定义求欧拉函数
{
    ll res=C;
    for(int i=2;i<=C/i;i++)
        if(C%i==0)
        {
            while(C%i==0) C/=i;
            res=res/i*(i-1);
        }
            
    if(C>1) res=res/C*(C-1);
    return res;
}

线 [ 1 , n ] 亦可用线性筛筛出[1,n]内的欧拉函数。


四、递推

[ 1 , n ] O ( n ) 求区间[1,n]的逆元,时间复杂度O(n)。

代码:

    int inv[N];
    inv[1]=1;
    for(int i=2;i<=20;i++)
        inv[i]=(long long)(mod-mod/i)*inv[mod%i]%mod;

五、递推求阶乘逆元

n ! 先求出n!的逆元,再倒序递推。

代码:

void init()
{
    fac[0]=1;
    for(int i=1;i<=n;i++)
        fac[i]=fac[i-1]*i%mod; 
        
    inv[n]=quick_pow(fac[n],mod-2,mod); //求出最大项阶乘的逆元
    for(int i=n-1;i>=0;i--)
        inv[i]=inv[i+1]*(i+1)%mod; //递推得到所有阶乘的逆元
}

猜你喜欢

转载自blog.csdn.net/njuptACMcxk/article/details/107520671