其他分享
首页 > 其他分享> > 数论(2)逆元

数论(2)逆元

作者:互联网

一、逆元理解

逆元是什么?
逆元就是扩大了概念的倒数。

定义:如果 ax≡1(mod M),就称x为在模M下 a的 逆元!
简单地说,如果一个数x满足 ax%M=1,那么x就称为在模M下 a的 逆元!

为什么说是扩大了概念的倒数呢,可见比起以前的倒数,只加了一个条件,即在后边加了一个 “%M",也可以这样理解,我们以前的倒数,也有这个条件,不过M是1。

二、逆元用处

有时候结果会让取模,除法只能用逆元取,如下:
(a/b)%M=(ainv[b])%M=(a%M)(inv[b]%M)%M

三、方法

(一、费马小定理)

费马小定理:
如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。 [1]

局限性:只能用于p为素数,且gcd(a,p)为1
改造一下费马小定理式子得到:a*a^(p-2)≡1(mod p)
这样,便和逆元式子对应起来了,a的逆元便是x,即是a^(p-2)
用快速幂就OK了
int quick(int a,int n,int p)
{
    if(n==0)
        return 1;
    if(n%2)
        return a*quick(a,n-1,p)%p;
    int tmp=quick(a,n/2,p);
    return tmp*tmp%p;
}

(二、扩展欧几里得定理)

局限性:gcd(a,M)=1,但并不要求M为素数,所以这个适用范围更广泛,而且稍快,推荐
ax≡1(mod M)
ax-My=1
即:ax+My=1
void exgcd(int a,int b,int &g,int &x,int &y)
{
    if(!b)
    {
        g=b;    x=1;    y=0;
    }
    else
    {
        exgcd(b,a%b,g,y,x);     y-=x*(a/b);
    }
}

(三、线性推)
洛谷大佬

inv[1] = 1;
for(int i = 2; i < p; ++ i)
    inv[i] = (p - p / i) * inv[p % i] % p;

四、例题

逆元板子
线性推
维护前后缀积线性推逆元

标签:倒数,数论,inv,int,逆元,ax,mod
来源: https://blog.csdn.net/czyhbo/article/details/115470754