几种逆元求法

1.不为素数

方法一,拓展欧几里德

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long c,n;
 4 long long d(long long a,long long b)
 5 {
 6     a=a%c;long long ans=1;
 7     while(b!=0){
 8         if(b&1) ans=(ans*a)%c;
 9         b/=2;
10         a=(a*a)%c;
11     }
12     return ans;
13 }
14 int main()
15 {
16     cin>>n>>c;
17     for(int i=1;i<=n;i++)
18         printf("%lld\n",d(i,c-2));
19 } 

方法二,线性打表

应用范围较小,必须要开很大数组,而且平时用不到。所以……咕咕咕


 

2.为素数

方法一,费马小定理

因为$a*a^{-1}Ξ1(mod p)$

费马小定理$a^pΞa{(mod p)}$

所以$a^{p-2}$Ξ$a^{-1}(mod p)$

所以$a^{p-2}$为逆元

具体实现

ll meng(ll x,ll k)
{
    ll ans=1;
    for(;k;k>>=1,x=x*x%p)
        if(k&1)
            ans=x*ans%p;
    return ans;
}
调用时meng(a(m),p-2)

这也是最常用的方法。

方法二,拓展欧几里德


 

阶乘逆元

理解一下,逆元实际上就是$1/?$
而$1/(n+1)!*(n+1)$其实就是$1/(n)!$,这样就求出来逆元了 。

    ni[n]=meng(jie[n],p-2);
    for(ll i=n-1;i>=1;i--)ni[i]=ni[i+1]*(i+1)%p;

完了

转载于:https://www.cnblogs.com/znsbc-13/p/11138112.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值