乘法逆元总结:

算单个数的逆元:

递推式:

inv[i]=(mod-mod/i)*inv[mod%i]%mod;

这种做法适用于递推。

当模数为质数时:

inv[i]=qmi(i,mod-2);

不是质数时,我们运用 \(exgcd\) 来计算。

阶乘乘积:

inv[n]=qmi(mul[n],mod-2);//mul为阶乘
for(int i=n-1;~i;i--) inv[i]=inv[i+1]*(i+1)%mod;

当然懒狗写法就是:

for(1->n) inv[i]=qmi(mul[i],mod-2);

求任意 \(n\) 个数的逆元:

和阶乘乘积类似。
首先我们计算 \(n\) 个数的前缀积,然后用快速幂计算 \(mul_n\) 的逆元 \(sv_n\)。
因为 \(sv_n\) 是 \(n\) 个数的积的逆元,当我们把它乘 \(a_n\) 就会和 \(a_n\) 的逆元抵消。

我们求出来 \(a_1\) 到 \(a_{n-1}\) 的积逆元,为 \(sv_i\)
于是,每个数的逆元 \(a_i^{-1}\) 就可以用 \(mul_{i-1}*sv_i\) 求得。

sv[n]=qmi(mul[n],mod-2);
for(int i=n-1;~i;i--) sv[i]=sv[i+1]*a[i+1]%mod;
for(int i=1;i<=n;i++) inv[i]=sv[i]*mul[i-1]%mod;