zoukankan      html  css  js  c++  java
  • 逆元

      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逆元

      

  • 相关阅读:
    通用应用程序设计
    咫尺与天涯
    SQL SERVER 自定义函数 split
    asp.net 页面实践执行顺序
    asp.net UpdatePanel 不能局部刷新问题汇总
    DataGrid GridView 单页javascript 表头排序
    存储过程分页方案
    数据库名、数据表名、字段名、主键、标识列相关查询
    c# web 缓存管理
    js笔记---拖动元素
  • 原文地址:https://www.cnblogs.com/szbszb/p/11338216.html
Copyright © 2011-2022 走看看