グローバルに書く
const int N_MAX = 100010;
ll Per[N_MAX] = {};
ll Per_inv[N_MAX] = {};
ll nCr(ll n, ll r){
if(n<r) return 0;
if (n == r || r == 0)
return 1;
else
return Per[n] * Per_inv[n-r] % mod * Per_inv[r] % mod;
}
ll mod_pow(ll a, ll b){
if(b==0) return 1;
if(b%2==1){
return a * mod_pow(a, b-1) % mod;
}
else{
return mod_pow(a*a % mod, b/2) % mod;
}
}
void prepare_nCr(){
Per[1] = 1;
FOR(i, 2, N_MAX){
Per[i] = i * Per[i-1] % mod;
}
Per_inv[1] = 1;
FOR(i, 2, N_MAX){
Per_inv[i] = mod_pow(Per[i], mod-2);
}
}
main()に書く
prepare_nCr();
追記 2021/05/12
- 上記ではPer_invの計算に無駄がある
- こうするといい
- (M!)^-1を求めてM, M-1, M-2, ...とかけていけばPer_invはpowなしに求まる
追記:MODセット
- 上記のnCrは事前準備するので107くらいが限界
- しかし109近い値(あるいはもっと大きい値)をMODで逆元計算したいときもある
- 個別にmod_powして逆元を求めればそれも可能
ll mod_pow(ll a, ll b){
if(b==0) return 1;
if(b%2==1){
return a * mod_pow(a, b-1) % mod;
}
else{
return mod_pow(a*a % mod, b/2) % mod;
}
}
ll to_plus(ll a){
a %= mod;
if(a<0) a+=mod;
return a;
}
ll Inv(ll a){
a = to_plus(a);
return mod_pow(a, mod-2);
}
ll ADD(ll x, ll y) { return (x+y) % mod; }
ll SUB(ll x, ll y) { return (x-y+mod) % mod; }
ll MUL(ll x, ll y) { return x*y % mod; }