①公式法
公式:     a1%p=a1%(ap)
 举个例子:     48%7=48%(4∗7)=48=2
 但是这个公式不能求那种本来就是分数的比如     41%7
 这种就要用到其他方法
②扩展欧几里得求逆元
扩展欧几里得是解决这种问题的:
       ax+by=gcd(a,b)
 互质的话     gcd=1
 那么      ax+by=1
 这个式子相当于
       ax%b=1
 也就是      ax≡1(mod b)
 就变成
       x≡a1(mod b)
 那么     a的逆元也就是     x啦
#include"iostream"
using namespace std;
const int MOD=1e9+7;
int x,y;
int exgcd(int a, int b, int &x, int &y,int c)
{
    if (b == 0)
    {
        x = c;
        y = 0;
        return a;
    }
    int d = exgcd(b, a % b, x, y,c);
    int t = x;
    x = y;
    y = t - a / b * y;
    return d;
}
int main()
{
    int N;
    while(cin>>N)
    {
        exgcd(N,MOD,x,y,1);
        cout<<((x%MOD)+MOD)%MOD<<endl;
    }
}
  ③逆元线性筛
假设要求     1到p−1 所有的逆元,阔以用线性筛
       p=ki+r
       ki+r≡0 (mod p)
 同时除一个     ir
       rk+i1=0 (mod p)
 所以
       i1≡−kr1 (mod p)
 而
      k=p/i
      r=p%i
 所以
       i1≡(−p/i)(p%i)     (mod p)
 这样求出来可能是负的,直接加上      p%i个p 把他变成正的
 完整的就是:
i1≡(p−p/i)(p%i) (mod p)
#include"bits/stdc++.h"
using namespace std;
const int maxn=5e4+5;
const int MOD=1e9+7;
long long inv[maxn];
int main()
{
    inv[0]=inv[1]=1;
    for(int i=2;i<=10000;i++)
    {
        inv[i]=((MOD-MOD/i)*inv[MOD%i])%MOD;
    }
    int N;
    while(cin>>N)
    {
        cout<<inv[N]<<endl;
    }
}
  ④费马小定理求逆元
如果能找到某个式子在模意义下等于1,那么变一下形就能找到他的逆元了,费马小定理就是这样
       ap−1≡1 (mod p)
       a⋅ap−2≡1 (mod p)
       a1≡ap−2 (mod p)
 所以逆元直接就是     ap−2,直接用快速幂算出来就行了
⑤单次快速求逆元,没看懂
LL inv(int x)
{
  LL r = 1;
  for (; x > 1; x = MOD % x)
    r = r * LL(-MOD/x) % MOD;
  return (r+MOD)%MOD;
}

京公网安备 11010502036488号