以前求逆元只会费马小定理和exgcd,看到别人都用递推求自己不会,今天学习了一下。
我们要在线性时间内求出
1−1,2−1…,(p−1)−1(modp)
p为质数
1∗1≡1(modp)⇒1−1≡1(modp)
a∗a−1≡1(modp) 1<a<p
令 k=⌊pa⌋,r=p mod a
p=k∗a+r 0<r<ak∗a+r≡0(modp)(k∗a+r)∗a−1∗r−1≡0(modp)k∗r−1+a−1≡0(modp)a−1≡−k∗r−1(modp)a−1=−⌊pa⌋∗(p mod a)−1 mod p=(p−⌊pa⌋)∗(p mod a)−1 mod p
inv[1]=1;
for(int i=2;i<=n;i++)
inv[i]=(p-p/i)*inv[p%i]%p;
同时,也可以据此来递归求出逆元,每次时间复杂度为 O(log2n)
int Get_inv(int n){
if(n==1)
return 1;
return (p-p/n)*(Get_inv(p%n))%p;
}
递归的时候p也必须为质数
一组例子,n=7,p=18