算单个数的逆元:
递推式:
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;