逆元模板(欧拉函数+费马小定理+快速幂)

*用一道模板题作为例子:

                                      B - 乘法逆元   51Nod - 1256 

给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。

Input

输入2个数M, N中间用空格分隔(1 <= M < N <= 10^9)

Output

输出一个数K,满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。

Sample Input

2 3

Sample Output

2

逆元模板分为两种情况 ,模数是素数和非素数的情况 :

欧拉适用于所有情况 :

//乘法逆元 此模板适用于模不确定的情况下(即有可能是素数,有可能不是)
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;

ll qpow(ll x,ll n,ll mod)
{
    ll ans=1;

    while(n)
    {
        if(n&1)
            ans=(ans*x)%mod;
            x=(x*x)%mod;
            n>>=1;
    }
    return ans;
}

ll eular(ll n)
{
  ll ans=n;
  ll tmp=sqrt(n+0.5);
  for(ll i=2;i<=tmp;i++)
  {
      if(n==1) break;

      if(n%i==0)
      {
         ans=ans/i*(i-1);
         while (n%i==0) n=n/i;
      }
  }

  if(n>1) ans=ans/n*(n-1);
  return ans;

}


int main()
{
    ios::sync_with_stdio(false);
    ll n,m;
   cin>>n>>m;

    cout <<qpow(n,eular(m)-1,m)%m<<endl;
     return 0;
}

再一个就是当 mod 是素数时,可以不用欧拉定理 直接将mod-2带入快速幂中 (素数的逆元为本身减一:phi(n)=n-1)

——————》》》不信点这里《《《————————


 

猜你喜欢

转载自blog.csdn.net/qq_41199502/article/details/82291105