除法取模与逆元

来源:互联网 发布:python和c语言 编辑:程序博客网 时间:2024/06/09 06:48

逆元:
对于正整数a和m,如果ax≡1(mod m),(即ax%m=1),那么把这个同余方程中x的最小正整数解叫做 a模m的逆元。
一个数有逆元的充分必要条件是gcd(a,m)=1,此时逆元唯一存在

除法取模

a/b mod m等价于a*b’mod m (b’是b模m的逆元)

下面是几种求逆元的方法

1.扩展欧几里得

代码如下

 #include<stdio.h> #define ll long long  ll exgcd(ll b,ll m,ll& x,ll& y){      if(!m){          x=1;          y=0;          return x;     }     else{         exgcd(m,b%m,y,x);         y-=x*(b/m);     }     return x; } int main(){     ll b,m,x,y;     while(scanf("%lld%lld",&b,&m)!=EOF){ //b有逆元的前提gcd(b,m)=1         x=exgcd(b,m,x,y);         x=(x%m+m)%m;         printf("%lld\n",x);//x即为b的逆元b'     }     return 0; }

2.费马小定理
在模m为素数的条件下有 b^(m-1)=1(mod m);
则 b模m的逆元b’ =b^(m-2)
用快速幂求即可。

代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<cmath>#include<string>#define LL long long  using namespace std;LL b,m;LL pow(LL x,LL n){      LL res=1;    while(n>0){        if(n&1)        res=(res*x);        x=(x*x);        n>>=1;    }    return res;}int main(){    while(cin>>b>>m){    cout<<pow(b,m-2)%m<<endl;     }    return 0;}

3.求逆元的一般公式

a/b mod m=a mod (m*b) /b

注意:实际上a mod (m*b)/b这种的对于所有的都适用,不区分互不互素,而费马小定理和扩展欧几里得算法求逆元是有局限性的,它们都会要求与互素,如果a与m不互素,那就没有逆元,这个时候需要a mod (bm)/b来搞(此时就不是逆元的概念了)。但是当a与m互素的时候,bm可能会很大,不适合套这个一般公式,所以大部分时候还是用逆元来搞.

0 0