①公式法

公式: 1 a % p = 1 % ( a p ) a \frac{1}{a} \%p=\frac{1\%(ap)}{a} a1%p=a1%(ap)
举个例子: 8 4 % 7 = 8 % ( 4 7 ) 4 = 8 4 = 2 \frac{8}{4}\%7=\frac{8\%(4*7)}{4}=\frac{8}{4}=2 48%7=48%(47)=48=2
但是这个公式不能求那种本来就是分数的比如 1 4 % 7 \frac{1}{4}\%7 41%7
这种就要用到其他方法

②扩展欧几里得求逆元

扩展欧几里得是解决这种问题的:
a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
互质的话 g c d = 1 gcd=1 gcd=1
那么 a x + b y = 1 ax+by=1 ax+by=1
这个式子相当于
a x % b = 1 ax\%b=1 ax%b=1
也就是 a x 1 ( m o d <mtext>   </mtext> b ) ax\equiv1 (mod\ b) ax1(mod b)
就变成
x 1 a ( m o d <mtext>   </mtext> b ) x\equiv\frac{1}{a}(mod\ b) xa1(mod b)
那么 a a a的逆元也就是 x x 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 1到p-1 1p1 所有的逆元,阔以用线性筛
p = k i + r p=ki+r p=ki+r
k i + r 0 <mtext>   </mtext> ( m o d <mtext>   </mtext> p ) ki+r\equiv 0\ (mod\ p) ki+r0 (mod p)
同时除一个 i r ir ir
k r + 1 i = 0 <mtext>   </mtext> ( m o d <mtext>   </mtext> p ) \frac{k}{r}+\frac{1}{i}=0\ (mod\ p) rk+i1=0 (mod p)
所以
1 i k 1 r <mtext>   </mtext> ( m o d <mtext>   </mtext> p ) \frac{1}{i}\equiv-k\frac{1}{r}\ (mod\ p) i1kr1 (mod p)

k = p / i k=p/i k=p/i
r = p % i r=p\%i r=p%i
所以
1 i ( p / i ) ( p % i ) <mtext>       </mtext> ( m o d <mtext>   </mtext> p ) \frac{1}{i}\equiv(-p/i)(p\%i)\ \ \ \ \ (mod\ p) i1(p/i)(p%i)     (mod p)
这样求出来可能是负的,直接加上 p % i p p\%i个p p%ip 把他变成正的
完整的就是:

1 i ( p p / i ) ( p % i ) <mtext>       </mtext> ( m o d <mtext>   </mtext> p ) \frac{1}{i}\equiv(p-p/i)(p\%i)\ \ \ \ \ (mod\ p) i1(pp/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,那么变一下形就能找到他的逆元了,费马小定理就是这样
a p 1 1 <mtext>   </mtext> ( m o d <mtext>   </mtext> p ) a^{p-1}\equiv1\ (mod\ p) ap11 (mod p)
a a p 2 1 <mtext>   </mtext> ( m o d <mtext>   </mtext> p ) a\cdot a^{p-2}\equiv1\ (mod\ p) aap21 (mod p)
1 a a p 2 <mtext>   </mtext> ( m o d <mtext>   </mtext> p ) \frac{1}{a}\equiv a^{p-2}\ (mod\ p) a1ap2 (mod p)
所以逆元直接就是 a p 2 a^{p-2} ap2,直接用快速幂算出来就行了

⑤单次快速求逆元,没看懂

LL inv(int x)
{
  LL r = 1;
  for (; x > 1; x = MOD % x)
    r = r * LL(-MOD/x) % MOD;
  return (r+MOD)%MOD;
}