This documentation is automatically generated by online-judge-tools/verification-helper
#include "cpp_src/math/ModularOperation.hpp"
V<Mint> fact, ifact, inv;
VV<Mint> small_comb;
void mod_init() {
const int maxv = 1000010;
const int maxvv = 5000;
fact.resize(maxv);
ifact.resize(maxv);
inv.resize(maxv);
small_comb = make_vec<Mint>(maxvv, maxvv);
fact[0] = 1;
for (int i = 1; i < maxv; ++i) {
fact[i] = fact[i - 1] * i;
}
ifact[maxv - 1] = fact[maxv - 1].inv();
for (int i = maxv - 2; i >= 0; --i) {
ifact[i] = ifact[i + 1] * (i + 1);
}
for (int i = 1; i < maxv; ++i) {
inv[i] = ifact[i] * fact[i - 1];
}
for (int i = 0; i < maxvv; ++i) {
small_comb[i][0] = small_comb[i][i] = 1;
for (int j = 1; j < i; ++j) {
small_comb[i][j] = small_comb[i - 1][j] + small_comb[i - 1][j - 1];
}
}
}
Mint comb(int n, int r) {
if (n < 0 || r < 0 || r > n) return Mint(0);
if (n < small_comb.size()) return small_comb[n][r];
return fact[n] * ifact[r] * ifact[n - r];
}
Mint inv_comb(int n, int r) {
if (n < 0 || r < 0 || r > n) return Mint(0);
return ifact[n] * fact[r] * fact[n - r];
}
// O(k)
Mint comb_slow(ll n, ll k) {
if (n < 0 || k < 0 || k > n) return Mint(0);
Mint res = ifact[k];
for (int i = 0; i < k; ++i) {
res = res * (n - i);
}
return res;
}
// line up
// a 'o' + b 'x'
Mint comb2(int a, int b) {
if (a < 0 || b < 0) return 0;
return comb(a + b, a);
}
// divide a into b groups
Mint nhr(int a, int b) {
if (b == 0) return Mint(a == 0);
return comb(a + b - 1, a);
}
// O(p + log_p n)
Mint lucas(ll n, ll k, int p) {
if (n < 0 || k < 0 || k > n) return Mint(0);
Mint res = 1;
while (n > 0) {
res *= comb(n % p, k % p);
n /= p;
k /= p;
}
return res;
}
struct ModPrepare {
ModPrepare() { mod_init(); }
} prep_mod;