結果
| 問題 |
No.117 組み合わせの数
|
| コンテスト | |
| ユーザー |
fmhr
|
| 提出日時 | 2016-09-10 10:01:18 |
| 言語 | Go (1.23.4) |
| 結果 |
AC
|
| 実行時間 | 359 ms / 5,000 ms |
| コード長 | 1,892 bytes |
| コンパイル時間 | 11,367 ms |
| コンパイル使用メモリ | 225,400 KB |
| 実行使用メモリ | 52,992 KB |
| 最終ジャッジ日時 | 2024-11-16 19:48:28 |
| 合計ジャッジ時間 | 12,474 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 1 |
ソースコード
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
sc.Split(bufio.ScanWords)
T := nextInt()
getFactInv()
for i := 0; i < T; i++ {
S := nextLine()
ai, _ := strconv.Atoi(strings.Split(S[2:len(S)-1], ",")[0])
bi, _ := strconv.Atoi(strings.Split(S[2:len(S)-1], ",")[1])
a := int(ai)
b := int(bi)
var ans int
switch S[0] {
case 'C':
ans = c(a, b)
case 'P':
ans = p(a, b)
case 'H':
ans = h(a, b)
}
fmt.Println(ans)
}
}
const MAX = 2000010
var MOD int = 1000000007 // 素数
var fact [MAX]int // 階乗
var factInv [MAX]int // 階乗の逆元
var inv [MAX]int
func getFactInv() {
// 最初に一度だけ実行
inv[1], fact[0], factInv[0] = 1, 1, 1
// nHkはn+k+1Ckとなるためn+kをとる
var i int
for i = 2; i < MAX; i++ {
inv[i] = inv[MOD%i] * (MOD - MOD/i) % MOD
}
for i = 1; i < MAX; i++ {
fact[i] = fact[i-1] * i % MOD
factInv[i] = factInv[i-1] * inv[i] % MOD
}
}
// 1 以上 N 以下の N 個の整数の中から,相異なる K 個の整数を選ぶパターンの数を C(N,K) と書きます.
func c(n, k int) int {
if k < 0 || k > n {
return 0
}
return fact[n] * factInv[k] % MOD * factInv[n-k] % MOD
}
// 1 以上 N 以下の N 個の整数の中から,相異なる K 個の整数を選び,順番に並べるパターンの数を P(N,K) と書きます.
func p(n, k int) int {
if k < 0 || k > n {
return 0
}
return fact[n] * factInv[n-k] % MOD
}
// 1 以上 N 以下の N 個の整数の中から,重複を許して K 個の整数を選ぶパターンの数を H(N,K) と書きます.
func h(n, k int) int {
if n == 0 && k == 0 {
return 1
}
if n == 0 {
return 0
}
return c(n+k-1, k)
}
var sc = bufio.NewScanner(os.Stdin)
func nextLine() string {
sc.Scan()
return sc.Text()
}
func nextInt() int {
i, _ := strconv.Atoi(nextLine())
return i
}
fmhr