求逆元

O(n)求逆元

结论

\(inv[i] = (mod − mod / i) \times inv[mod \% i] \% mod\)

证明

\(t = mod / i,k = mod \% i\)

则有:

\(t \times i + k \equiv 0 \ \% mod\)

有:

\(−t∗i \equiv k \ \% mod\)

两边同时除以 \(i \times k\) 得到:

\(−t∗inv[k] \equiv inv[i] \ \% mod\)

即:

\(inv[i] \equiv −mod / i∗inv[mod \% i] \ \%mod\)

即:

\(inv[i] \equiv (mod − mod / i)∗inv[mod \% i] \ \% mod\)

证毕。

  • 适用于模数 \(mod\)质数的情况,能够 \(O(N)\) 时间求出 \(1−N\) 对模 $ mod $ 的逆元。

代码

inv[1] = 1;
for(int i = 2;i<=1e7;i++)
	inv[i] = 1ll*(mod-mod/i)*inv[mod%i]%mod;

阶乘递推求逆元

阶乘求逆元咱也不太会证明

只放代码好了

fac[0] = 1;
for(int i = 1;i<=nd;i++) fac[i] = fac[i-1]*i%mod;
inv[nd] = ksm(fac[nd]);
for(int i = nd-1;i>=0;i--) inv[i] = inv[i+1]*(i+1)%mod;

扩欧求逆元

求exgcd(e, m)—>利用欧几里得算法不断递归直到x=1,y=0—>反向递归求出第一层的x和y,x即为e模m的逆元

inline 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;
}
inline int inv(int x){
	int a,b;
	exgcd(mod,x,b,a);
	return a+((a>>31)&mod);//这个右移31位就很玄学,欢迎各位解释一下
}
posted @ 2023-06-16 20:19  cztq  阅读(12)  评论(0编辑  收藏  举报