乘法逆元

1,乘法逆元

   ax≡1(mod p),且gcd(a,p)=1(a,p互质),则a关于p的乘法逆元为x

2,费马小定理

假如a是一个整数,p是一个质数,那么( ap - a )是p的倍数,可以表示为 

    ap ≡a(mod p)

如果a不是p的倍数,p是一个质数,则

    ap-1 = 1(mod p)

3,扩展欧几里得

已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足ax+by=gcd(a,b)

 

费马小定理求逆元:

  ap-1=1(mod p) ,则逆元x=ap-2(快速幂求)

扩展欧几里得求逆元:

  ax≡1(mod p),则ax-py=1,把-y写成+的形式,即ax+py=1,求得逆元

 

1,扩展欧几里得求逆元(a,b互质,否则无解)

函数返回值为a,b的最大公约数,x为a的逆元

 1 int ex_gcd(int a,int b,int &x,int &y)
 2 {
 3     int ret,temp;
 4     if(b==0){
 5         x = 1;
 6         y = 0;
 7         return a;
 8     }
 9     ret = ex_gcd(b,a%b,x,y);
10     temp = x;
11     x = y;
12     y = temp-a/b*y;
13     return ret;
14 }
View Code

 

 2,快速幂求逆元( p是质数)

 ap-1=1(mod p) ,则逆元x=ap-2

 1 long long quick_inv(long long a,int p){
 2      int s = p-2;
 3      long long ans = 1,pos = a;
 4      while(s){
 5          if(s%2) ans = ans*pos%p;
 6          pos = pos*pos%p;
 7          s/=2;
 8      }
 9      return ans%p;
10 }
View Code

 

3,通过递推求1~n的逆元(n较小,p是质数)

 公式推导:记 i 的逆元为 i-1

   p = k*i+r, 令r < i,则 k = p/i , r = p%i

   k*i + r ≡ 0 (mod p)

           ↓( 两边同时乘以 r-1,i-1)

   k*r-1 + i-1 ≡ 0(mod p)

   i-1 = -k * r -1 (mod p)

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

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

   inv[1] = 1;

1 //求1~n的逆元,p为模数,n<=p-1
2 void n_inv(int n){
3     inv[1] = 1;
4     for(int i = 2;i <= n ;i++){
5         inv[i] = (p-p/i)*inv[p%i]%p;
6     }
7 }
View Code

4,通过递推求1!~ n! 的逆元

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

void fac_inv(int n){
    fac[1] = 1;
    for(int i = 2;i <= n;i++)
        fac[i] = fac[i-1]*i;
    inv = quick_inv(fac[n],p);
    for(int i = n-1;i>0;i--)
        inv[i] = inv[i+1]*(i+1)%p;
}
View Code

 

  

posted @ 2019-04-10 11:15  Obliviate  阅读(189)  评论(0)    收藏  举报