乘法逆元

乘法逆元

定义

对于一个线性同余方程 \(ax \equiv 1 \pmod b\),则 \(x\) 称为 \(a \bmod b\) 的逆元,记作 \(a^{-1}\)
\(a \bmod b\) 的逆元存在当且仅当 \(a\perp p\)

费马小定理求逆元

对于\(p\)为质数,由费马小定理

\[a^{p-1}\equiv 1\pmod b \]

\[\begin{align*} ax &\equiv a^{b-1} \pmod b\\ x &\equiv a^{b-2} \pmod b \end{align*} \]

于是可以用快速幂求解

il int qpow(int a,int b,int p){
    ri int as=1;
    while(b>0){
        if(b&1) as=as*a%p;
        a=a*a%p,b>>=1;
    }
    return as;
} 
il int Inv(int a,int p){
    return qpow(a,p-2,p);
}

扩展欧几里得法求逆元

递归解线性同余方程 \(ax \equiv 1 \pmod b\)即可

il void exgcd(cs int a,cs int b,int &x,int &y,int &g){
    if(!b) return x=1,y=0,g=a,void();
    return exgcd(b,a%b,y,x,g),y-=x*(a/b),void();
}
il int Inv(int a,int p){
    int x=0,y=0,g=0;
    exgcd(a,p,x,y,g);
    return (x%p+p)%p;
}

线性求1~n的逆元

\[x^{-1}\equiv \begin{cases} 1, x=1 \\ - \lfloor \frac{p}{x} \rfloor \cdot (p\bmod x)^{-1} ,otherwise \end{cases} \pmod p \]

il void solve(int n,int p){
    inv[1]=1;
    for(ri int i=2;i<=n;++i){
        inv[i]=(-p/i*inv[p%i]%p+p)%p;
    } 
    return;
}

线性求任意n个数的逆元

首先计算 \(n\) 个数的前缀积,记为 \(s_i\),然后使用快速幂或扩展欧几里得法计算 \(s_n\) 的逆元,记为 \(sv_n\)
因为 \(sv_n\)\(n\) 个数的积的逆元,所以当我们把它乘上 \(a_n\) 时,就会和 \(a_n\) 的逆元抵消,于是就得到了 \(a_1\)\(a_{n-1}\) 的积逆元,记为 \(sv_{n-1}\)
同理我们可以依次计算出所有的 \(sv_i\),于是 \(a_i^{-1}\) 就可以用 \(s_{i-1} \times sv_i\) 求得。
所以我们就在 \(O(n + \log p)\) 的时间内计算出了 \(n\) 个数的逆元。

il void solve(int n,int p){
    s[0]=1;
    for(ri int i=1;i<=n;++i){
        s[i]=s[i-1]*a[i]%p;
    } 
    sv[n]=Inv(s[i],p);
    for(ri int i=n;i;--i){
        sv[i-1]=sv[i]*a[i]%p;
    }
    for(ri int i=1;i<=n;++i){
        inv[i]=s[i-1]*sv[i]%p;
    }    
    return;
}

edit

posted @ 2023-03-17 09:43  雨夜风月  阅读(18)  评论(0编辑  收藏  举报