逆元

  1、何为逆元

  有的时候,我们要在模p的意义下,求一个事件的概率期望,这就要用逆元,因为分数很容易除不尽,而a/b在模p意义下即为a*(b在模p意义下的逆元),这样就能避免无限循环的情况。

  一个数的逆元定义为:数为a,模数为p,逆元为b,那么,满足a*bmod p=1.

  2.1、费马小定理求逆元

  费马小定理能够求数与模数互质情况的逆元,根据费马小定理,若a、p互质,b为a的逆元,那么ap-1 mod p=1,也就是说,ap-1 mod p=a*b mod p,即b=ap-2 mod p,所以逆元为原数的p-2次幂模p。

  如何求呢?我们考虑到了快速幂,即可logp求出逆元。

  以下为代码:

复制代码
#include<bits/stdc++.h>
using namespace std;
long long n,p,y,he,ans;
int main()
{
    scanf("%lld%lld",&n,&p);//读入n、p
    y=p-2;//乘p-2次
    he=1;
    ans=n;
    while(y)
    {
        if (y&1) he=(he*ans)%p;
        ans=(ans*ans)%p;
        y/=2;//快速幂
    }
    printf("%lld",ans*he%p);//输出
    return 0;
}
复制代码

  2.2、扩展欧几里得算法求逆元

  我们用扩展欧几里得算法可以求ax+by=1的值一组解,再通过将a作为所求数,b为模数,明显的,求出的x即为a模p的逆元。

  代码如下:

复制代码
#include<bits/stdc++.h>
using namespace std;
int a,p,x,y;
void gcd(int a,int b,int &x,int &y)//扩展欧几里得算法
{
    if (b==0)
    {
        x=1;
        y=0;
        return;
    }
    gcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-(a/b)*y;
}
int main()
{
    scanf("%d%d",&a,&p);
    gcd(a,p,x,y);
    printf("%d",(x+p)%p);//注意x可能为负数
    return 0;
}
复制代码

  3、线性求1~n逆元

  

posted @   冰逝  阅读(223)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥
点击右上角即可分享
微信分享提示