n!、nCr、nPrをmodで割った余りを求めるクラスを作りました。
class mComb {
private:
bool _calced = false;
int _mod = 1000000007;
vector<long long> _fac, _invf, _inv;
public:
void setmod(int m) {
_mod = m;
}
void comb_init(int n) {
_fac.resize(n + 1);
_invf.resize(n + 1);
_inv.resize(n + 1);
_fac[0] = 1;
_fac[1] = 1;
_invf[0] = 1;
_invf[1] = 1;
_inv[1] = 1;
for (int i = 2; i <= n; i++) {
_fac[i] = _fac[i - 1] * i % _mod;
_inv[i] = _mod - _inv[_mod % i] * (_mod / i) % _mod;
_invf[i] = _invf[i - 1] * _inv[i] % _mod;
}
_calced = true;
}
long long F(int n) {
return _fac[n];
}
long long C(int n, int k) {
if (!_calced) {
cerr << "not initialized\n";
exit(1);
}
return _invf[k] * _invf[n - k] % _mod * _fac[n] % _mod;
}
long long P(int n, int k) {
if (!_calced) {
cerr << "not initialized\n";
exit(1);
}
return _invf[n - k] * _fac[n] % _mod;
}
long long H(int n, int k) {
if (!_calced) {
cerr << "not initialized\n";
exit(1);
}
return _invf[k] * _invf[n - 1] % _mod * _fac[n + k - 1] % _mod;
}
};
まあ、見ればわかると思います。