逆元的几种求法

我们知道模运算有如下的运算规则:

  • (a+b)%p=(a%p+b%p)%p
  • (a-b)%p=(a%p-b%p)%p
  • (a*b)%p=(a%p*b%p)%p

模运算与基本四则运算有些相似,但是除法例外。

既然除一个数不满足取模,我们就改成让他乘一个数,使得乘之后取模的结果与原答案相同。乘的这个数就是乘法逆元。

乘法逆元的定义:

对于正整数a和p(假设a存在乘法逆元,即a和p互质),如果有ax≡1(mod p),那么把x的最小正整数解叫做a模m的乘法逆元。

 


 

知道了逆元的作用,我们来介绍几种逆元的求法。(以模数为1e9+7为例)

1.费马小定理:

  费马小定理(Fermat's little theorem)是数论中的一个重要定理,在1636年提出,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)。(摘自百度百科)

  应用费马小定理可求得a模p的乘法逆元,inv(a)=a(p-2)modp。(p为质数)

  推导:

    a(p-1)≡1(mod p) =>   a· a(p-2)  ≡1  (mod p)   =>   a(p-2)≡a-1  (mod p)

  有了费马小定理用快速幂就能求得a模p的逆元,时间复杂度为O(log N)

  

 1 const int mod=1e9+7;
 2 typedef long long LL;
 3 
 4 LL Fast_pow(LL a,int b){
 5     LL ans=1;
 6     while(b){
 7         if(b&1)
 8             ans=ans*a%mod;
 9         a=a*a%mod;
10         b>>=1;
11     }
12     return ans;
13 }
14 
15 LL inv(LL a,int p){
16     return Fast_pow(a,p-2);
17 }

 

2.扩展欧几里得:

  扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理)。(摘自百度百科)

  根据逆元的定义,求a模p的逆元就是求解ax≡1(mod p)的最小正整数解,也就是相当于求解不定方程ax-py=1 (a和p互质) 。对于不定方程的求解,我们可以使用扩展欧几里得。

  时间复杂度为O(log N)

 

 1 const int mod=1e9+7;
 2 typedef long long LL;
 3 
 4 int exEuclid(int a,int b,int & x,int &y){
 5     if(!b){
 6         x=1;
 7         y=0;
 8         return a;
 9     }
10     int r=exEuclid(b,a%b,x,y);
11     int t=x;
12     x=y;
13     y=t-a/b*y;
14     return r;
15 }
16 
17 LL inv(LL a){
18     LL x,y;
19     int temp=exEuclid(a,mod,x,y);
20     return temp==1?(x+mod)%mod:-1; //若gcd(a,p)!=1 (即a和p不互质),则不存在逆元,返回-1
21 }

 

 

3.线性递推:

  若做题时需要求出1~p范围内所有的逆元,用上述方法时间复杂度O(N logN)。若可线性递推,O(N)时间内即可求出所有答案。

  递推式如下:

    inv[i]=(p-p/i)*inv[p%i]%p

  推导:

    设 t=p/i  k=p%i,那么

    => t*i+k≡0 (mod p)

    => -t*i≡k (mod p)

    两边同除 i*k ,得

    -t*inv[k]≡inv[i](mod p)

    替换t k,得到

    inv[i]=(p-p/i)*inv[p%i]%p

    

1 void init(){
2     inv[1]=1;
3     for(int i=2;i<p;i++) {
4         inv[i]=(p-p/i)*A[p%i]%p;
5     }
6 }

 

4.特例 

  对于求阶乘的逆元也有一个递推式:

    inv[i]=inv[i+1]*(i+1)%p

  推导如下:

    i ! · x ≡ 1 (mod p)

  =>  (i-1) ! · (i · x) ≡ 1 (mod p)

  

    

 

 

 

 

END

 

 

 如发现错误 请各位神犇指正。

posted @ 2018-08-23 02:02  Beethoven_ov  阅读(751)  评论(0编辑  收藏  举报