結果
問題 | No.117 組み合わせの数 |
ユーザー | kimiyuki |
提出日時 | 2016-11-25 23:57:39 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 1,651 bytes |
コンパイル時間 | 374 ms |
コンパイル使用メモリ | 51,200 KB |
実行使用メモリ | 19,444 KB |
最終ジャッジ日時 | 2024-05-05 13:34:31 |
合計ジャッジ時間 | 1,382 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ソースコード
#include <cstdio> #include <vector> #include <cassert> #define repeat(i,n) for (int i = 0; (i) < (n); ++(i)) #define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i)) typedef long long ll; using namespace std; ll powi(ll x, ll y, ll p) { // O(log y) assert (y >= 0); x = (x % p + p) % p; ll z = 1; for (ll i = 1; i <= y; i <<= 1) { if (y & i) z = z * x % p; x = x * x % p; } return z; } ll inv(ll x, ll p) { // p must be a prime, O(log p) assert ((x % p + p) % p != 0); return powi(x, p-2, p); } const int mod = 1e9+7; int fact(int n) { static vector<int> memo(1,1); if (memo.size() <= n) { int l = memo.size(); memo.resize(n+1); repeat_from (i,l,n+1) memo[i] = memo[i-1] *(ll) i % mod; } return memo[n]; } int ifact(int n) { static vector<int> memo(1,1); if (memo.size() <= n) { int l = memo.size(); memo.resize(n+1); repeat_from (i,l,n+1) memo[i] = inv(fact(i), mod); } return memo[n]; } int choose(int n, int r) { // O(n) at first time, otherwise O(1) if (n < r) return 0; r = min(r, n - r); return fact(n) *(ll) ifact(n-r) % mod *(ll) ifact(r) % mod; } int permute(int n, int r) { if (n < r) return 0; return fact(n) *(ll) ifact(n-r) % mod; } int multichoose(int n, int r) { return choose(n+r-1, r); } int main() { int n; scanf("%d", &n); while (n --) { char f; int n, k; scanf(" %c(%d,%d)", &f, &n, &k); printf("%d\n", f == 'C' ? choose(n,k) : f == 'P' ? permute(n,k) : f == 'H' ? multichoose(n,k) : -1); } return 0; }