逆元

问题引入

对于取余运算,有以下一些性质:

唯独除法是不满足的:

证明:

而对于一些题目,我们必须在中间过程中进行求余,否则数字太大,电脑存不下,那如果这个算式中出现除法,我们就需要逆元了,将除法运算转换为乘法运算

定义

除法取余的情况下,就是乘上这个数的逆元。即:

这样就把除法取余,装换成了乘法取余。

逆元的性质

  • 唯一性

    给定一个数a,若存在模p下的逆元c,c一定唯一。

  • 自反性

    c是a的逆元,a也是c的逆元。

逆元的求解

扩展欧几里得算法

模数可以不为质数,满足gcd(a,b)=1即可

  • 定义

  • 代码模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
    if(!b){
    x=1;y=0;
    return a;
    }
    ll d=exgcd(b,a%b,x,y);
    ll t=x;
    x=y;
    y=t-(a/b)*y;
    return d;
    }

    即(取非负——a<b)逆元为x:

    1
    cout<<(x%b+b)%b<<endl;

费马小定理

只适用于模数为质数的情况,如果模数不是质数,可以变换一下,用欧拉定理。

如果p是一个质数(一般为1e9+7),且a不是p的倍数则有:

根据同余除法定理,两边同除以a:

所以:

p是素数,所以a肯定就无法被p整除啊,所以最后就得出a^(p-2)为x的逆元。

  • 代码模板:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ll quickpow(ll a,ll b){
    ll res=1;
    while(b){
    if(b&1)
    res=res*a%p;
    a=a*a%p;
    b>>=1;
    }
    return res;
    }

    res即为所求逆元。