学习笔记——乘法逆元

乘法逆元

本文来自这里!

乘法逆元是数论中重要的内容,也是 ACM 中常用到的数论算法之一。所以,如何高效的求出乘法逆元是一个值得研究的问题。

这里我们只讨论当模数为素数的情况,因为如果模数不为素数,则不一定每个数都有逆元。

定义

m o d p mod p modp的意义下我们把 x x x 的乘法逆元写作为 x − 1 ​ ​ x ^ {-1}​​ x1
乘法逆元有如下的性质:

在这里插入图片描述
乘法逆元的一大应用是模意义下的除法,除法在模意义下并不是封闭的,但我们可以根据上述公式,将其转化为乘法。

在这里插入图片描述
下面我们看几种求乘法逆元的方法。

扩展欧几里得

本部分来自这里!
关于扩展欧几里得算法

这个方法十分容易理解,而且对于单个查找效率似乎也还不错,比后面要介绍的大部分方法都要快(尤其对于   m o d   p \bmod {p} modp 比较大的时候)。

这个就是利用拓欧求解 线性同余方程 a ∗ x ≡ c ( m o d b ) a*x \equiv c \pmod {b} axc(modb) c = 1 c=1 c=1的情况。我们就可以转化为解 a ∗ x + b ∗ y = 1 a*x + b*y = 1 ax+by=1这个方程。

而且这个做法还有个好处在于,当 a ⊥ p a \bot p ap (互质),但 p 不是质数的时候也可以使用。

代码比较简单:

void Exgcd(int a,int b,int &x,int &y) 
{
    if (!b) x=1,y=0;
    else Exgcd(b,a%b,y,x), y-=a/b*x;
}
int main() {
    int x, y;
    Exgcd (a,p,x,y);
    x=(x%p+p)%p;
    printf ("%d\n",x); //x是a在mod p下的逆元
}

费马小定理

费马小定理形式很简单,就是
在这里插入图片描述

实际上,它是欧拉定理的一个特殊情况,p为素数时
在这里插入图片描述
显然可得,p为素数时 a p − 2 a^{p-2} ap2就是我们要求的逆元。当然,p不为素数你也可以试试去求欧拉函数(试试就逝世)。
算法用快速幂就好。

typedef  long long ll;
ll pow_mod(ll x, ll n, ll mod){
    ll res=1;
    while(n>0){
        if(n&1)res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}

递推公式

原文

公式如下
在这里插入图片描述
神犇qhy手推
(第二行以后都是模p意义下的)在这里插入图片描述

#include<cstdio>
using namespace std;
long long n,p;
long long ans[5000010];
int main()
{
   scanf("%lld%lld",&n,&p);
   ans[0]=0,ans[1]=1;
   for(long long i=2;i<=n;i++) 
     {
     ans[i]=(long long)(p-p/i)*ans[p%i]%p;
       printf("%lld\n",ans[i]); 
     }
}

P.S. 还有一种阶乘的做法,这里不再描述,引用其他dalao的一段博客

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值