求逆元的四大基本方法
Posted star17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求逆元的四大基本方法相关的知识,希望对你有一定的参考价值。
前几天在u裙见到有人说求逆元四大方法,就来写一下(
1、快速幂
仅限p是质数
a^(p-1)≡1(mod p),则a*a^(p-2)≡1(mod p),即a的逆元为a^(p-2)
代码
const int P=998244353;
int pow(ll a,ll p)
{
ll r=1;
for(;p;p>>=1,a=a*a%P;)if(p&1)r=r*a%P;
return r;
}
int inv(ll a)
{
return pow(a,P-2);
}
2、欧几里得
要求a与p互质
考虑求a的逆元就是解一个方程ax≡1(mod b),即ax+by=1
这就很好做了,注意exgcd之后要把x搞成正的
代码
void exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
int inv(int a,int p)
{
int x,y;
exgcd(a,p,x,y);
x=((x%b)+b)%b;
}
3、递推
这个做法应该人人都会?
\\(
设ax+b=P,其中1<x<P,0\\leq b<x\\\\
则ax+b≡0(mod P)\\\\
同时乘上x^{-1}b^{-1}得到\\\\
a*b^{-1}+x^{-1}≡0(mod P)\\\\
x^{-1}≡-a*b^{-1}(mod P)\\\\
\\)
inv[1]=1;
for(int i=2;i<P;i++)inv[i]=(P-P/i*inv[P%i])%P;
还有一种递推阶乘的逆元,大概就是预处理一下阶乘f,随便找个方法求出inv(f[n]),
然后for(int i=n-1;i>=1;i--)inv[i]=inv[i+1]*(i+1)%P;
inv[i]表示f[i]的逆元
小拓展:O(n)求a1、a2、...、an的逆元
记\\(f_i=a_1*a_2*...*a_i,g_i为f_i的逆元\\)
用类似阶乘逆元的方式可以求出g_i
最后\\(a_i的逆元就是g_i*f_{i-1}\\)
4、牛顿迭代法
先鸽这,有空再补
以上是关于求逆元的四大基本方法的主要内容,如果未能解决你的问题,请参考以下文章