乘法逆元 学习总结

基本都是抄的大神写好的东西,主要作为一个复习,加深印象。

定义:若整数 b,m 互质,并且 b|a(b整除a),则存在一个整数 x,使得 a/b ≡ a * c (mod m)则称 x 为 b 的模 m 法逆元,记为 b-1(mod m)

那么我们如何求 b-1(mod m)

根据定义,a/b ≡ a * b-1 ≡ a/b * b * b-1 (mod m),那么 b * b-1 ≡ 1 (mod m)。

到这里可以用两种方法求解b-1(mod m):

1、费马小定理。

  费马小定理:若p是质数,则对于任意整数 a,有 ap ≡ a (mod p)。那么 bp ≡ b (mod p) → b * bp-1 ≡ b (mod p) → b * bp-2 ≡ 1 (mod p)。因此,当模数 p 为质数时,bp-2 即为 b-1(mod p) 。因此我们可以使用快速幂求出逆元。

 

int qpow(int i,int k,int mod)
{
    int res=1;
    while(k)
    {
        if(k&1) res=(LL)res*i%mod;
        i=(LL)i*i%mod;
        k>>=1;
    }
    return res;
}

int main()
{
    int invb=qpow(b,p-2,p); //p是质数,b的逆元就是b^(p-2) mod p 
    return 0;
}

 

 

 

2、解同余方程。

  因为 b * b-1 ≡ 1 (mod m),那么同余方程 b * x ≡ 1 (mod m) 的解就是逆元,相当于解方程 b * x + m * y = 1,根据扩展欧几里得,只要保证了 b,m 互质,我们就可以用这种方法求出逆元。

 

void exgcd(int a,int b,int &x,int &y)
{
    if(b==0) {x=1;y=0;return;}
    exgcd(b,a%b,x,y);
    int z=x;x=y;y=z-a/b*y;
}

int main()
{
    int x,y;
    exgcd(b,p,x,y);
    x=(x%p+p)%p;
    return 0;
}

 

 

 

当然还有其他特殊情况我们需要选用特殊的方法来求逆元:

1、求解 1~n 这样一串连续数的逆元:

  已知 1-1 ≡ 1 (mod p)

  设 p = k * i + r,即 ⌊p/i⌋ = k,p%i = r

  那么 k * i + r ≡ 0 (mod p)

  左右同乘以i-1r-1,得 k * r-1 + i-1 ≡ 0 (mod p)

  移项,得 i-1 ≡ -k * r-1 (mod p)

  因为k = ⌊p/i⌋,r = p%i

  可得,i-1 = -⌊p/i⌋ * (p%i)-1 (mod p)

  为保证逆元为正数,令

  i-1 = (p-⌊p/i⌋) * (p%i)-1 (mod p)

  那么我们就可以利用这个式子递推出 1~n 的逆元。

 

int main()
{
    scanf("%d%d",&n,&p);
    inv[1]=1;
    for(int i=2;i<=n;i++) inv[i]=(LL)(p-p/i)*inv[p%i]%p;
    for(int i=1;i<=n;i++) printf("%d\n",inv[i]);
    return 0;
}

 

 

2、求 1~n 的阶乘数的逆元

  因为$\dfrac {1}{\left( i+1\right) !}\times \left( i+1\right) =\dfrac {1}{i!}$

  设 inv[i] 为 i! 的逆元,那么 inv[i+1] * (i+1) = inv[i]

  利用这个关系我们就可以在知道 inv[n] 的情况下逆推出 1~n 的阶乘的逆元了。

 

int qpow(int i,int k,int mod)
{
    int res=1;
    while(k)
    {
        if(k&1) res=(LL)res*i%mod;
        i=(LL)i*i%mod;
        k>>=1;
    }
    return res;
}

int main()
{
    scanf("%d%d",&n,&p);
    fact[0]=1;
    for(int i=1;i<=n;i++) fact[i]=(LL)fact[i-1]*i%p;
    invi[n]=qpow(fact[n],p-2,p);
    for(int i=n-1;i>=1;i--) invi[i]=(LL)invi[i+1]*(i+1)%p;
    return 0;
}

 

转载于:https://www.cnblogs.com/BakaCirno/p/11515718.html

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值