线性预处理组合数,一般来说只是需要用一个组合数,当MOD大于n和m的时候可以这样求,否则应该用扩展Lucas定理。
const ll MOD = 1e9 + 7; const int MAXN = 1e6; ll inv[MAXN + 5], fac[MAXN + 5], invfac[MAXN + 5]; void init_C(int n) { inv[1] = 1; for(int i = 2; i <= n; i++) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD; fac[0] = 1, invfac[0] = 1; for(int i = 1; i <= n; i++) { fac[i] = fac[i - 1] * i % MOD; invfac[i] = invfac[i - 1] * inv[i] % MOD; } } inline ll C(ll n, ll m) { if(n < m) return 0; return fac[n] * invfac[n - m] % MOD * invfac[m] % MOD; }
错位排列,D[i]表示i个(不同的)元素全部不在应该在的位置(升序/降序等唯一指定位置)的种类数,可以通过dp求出来,但是还是抄模板方便。
const ll MOD = 1e9 + 7; const int MAXN = 1e6; //特殊定义D[0]为1 D[0] = 1, D[1] = 0; for(int i = 2; i <= MAXN; i++) { if(i & 1) { D[i] = ((ll)i * D[i - 1] - 1ll) % MOD; if(D[i] < 0) D[i] += MOD; } else D[i] = ((ll)i * D[i - 1] + 1ll) % MOD; }
来源:https://www.cnblogs.com/KisekiPurin2019/p/12269963.html