乘法逆元

关于乘法逆元  a*b=1( mod p )   a是b关于p的乘法逆元

(1)   解决除法不能取摸的问题

(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  /  b) % p = (a%p  /  b%p) %p  (错)  这个是不对的  关于这个的正确运算 我们可以求 b关于p的乘法逆元 x

(a /  b ) % p=  (a%p)*( x % p)%p;   (对) 

求a关于b的乘法逆元    只有gcd(a,b) 才有逆元

(1)拓展欧几里德算法

#include<bits/stdc++.h>
using namespace std;
void exgcd(int a,int b,int &x,int &y)
{
   if(b==0)
   {
      x=1,y=0;
      return;
   }
   exgcd(b,a%b,x,y);
   int xx=x;
   x=y;
   y=xx-a/b*y;

}
int32_t main()
{
     int a=5;
     int b=3;
     if(__gcd(a,b)==1)
     {
         int x;int y; exgcd(a,b,x,y);
         cout<<(x%b+b)%b<<endl;
         // x  a guan yu b de chengfaniyuan
     }
}

 (1)费马小定理   p 都是素数 gcd(a,p)=1;   a^(p-2)  与  a  互为乘法逆元 (mod p);

    这样求出来的不一定是最小的逆元  取摸p就可以求出最小的了

#include<bits/stdc++.h>
using namespace std;
int quick(int a,int n)
{
   int ans=1;
   int t=a;
   while(n!=0)
   {
      if(n%2==0) {n=n/2; t=t*t;}
      else if(n%2==1) {n--; ans*=t; }
   }
   return ans;
}

int32_t main()
{
     int a=5;
     int b=3;
     if(__gcd(a,b)==1)
     {
         cout<<quick(a,b-2)%b<<endl;
     }
}

(3)这个我也不知道  当p是个质数的时候    inv(a) = (p - p / a) * inv(p % a) % p   不证明  (下面代码来源)  https://www.cnblogs.com/linyujun/p/5194184.html#3804000

#include<cstdio>
typedef long long LL;
LL inv(LL t, LL p) 
{
//求t关于p的逆元,注意:t要小于p,最好传参前先把t%p一下 return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p; } int main(){ LL a, p; while(~scanf("%lld%lld", &a, &p)){ printf("%lld ", inv(a%p, p)); } }

 求n个数的乘法逆元 O(n)

#include<cstdio>
const int N = 200000 + 5;
const int MOD = (int)1e9 + 7;
int inv[N];
int init(){
    inv[1] = 1;
    for(int i = 2; i < N; i ++){
        inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
    }
}
int main(){
    init();
}
原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/9773597.html