求逆元
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位就很玄学,欢迎各位解释一下
}
梦与现实间挣扎着,所求为何
你可以借走我的文章,但你借不走我的智慧 虽然我是傻逼本文来自博客园,作者:cztq,转载请注明原文链接:https://www.cnblogs.com/cztq/p/17486451.html