結果
問題 | No.2468 Mercurialist |
ユーザー | 👑 SPD_9X2 |
提出日時 | 2023-05-09 07:50:28 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 298 ms / 2,000 ms |
コード長 | 2,598 bytes |
コンパイル時間 | 256 ms |
コンパイル使用メモリ | 82,508 KB |
実行使用メモリ | 113,896 KB |
最終ジャッジ日時 | 2024-04-30 21:04:33 |
合計ジャッジ時間 | 6,643 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 84 ms
94,720 KB |
testcase_01 | AC | 82 ms
93,592 KB |
testcase_02 | AC | 82 ms
93,520 KB |
testcase_03 | AC | 266 ms
110,472 KB |
testcase_04 | AC | 273 ms
113,528 KB |
testcase_05 | AC | 298 ms
112,808 KB |
testcase_06 | AC | 116 ms
113,224 KB |
testcase_07 | AC | 104 ms
108,712 KB |
testcase_08 | AC | 248 ms
105,956 KB |
testcase_09 | AC | 88 ms
94,488 KB |
testcase_10 | AC | 237 ms
103,296 KB |
testcase_11 | AC | 92 ms
96,076 KB |
testcase_12 | AC | 83 ms
93,292 KB |
testcase_13 | AC | 83 ms
93,676 KB |
testcase_14 | AC | 249 ms
110,464 KB |
testcase_15 | AC | 108 ms
107,632 KB |
testcase_16 | AC | 105 ms
108,000 KB |
testcase_17 | AC | 105 ms
108,056 KB |
testcase_18 | AC | 187 ms
111,580 KB |
testcase_19 | AC | 187 ms
109,572 KB |
testcase_20 | AC | 195 ms
110,712 KB |
testcase_21 | AC | 234 ms
113,896 KB |
testcase_22 | AC | 96 ms
101,568 KB |
testcase_23 | AC | 147 ms
112,664 KB |
testcase_24 | AC | 160 ms
111,036 KB |
testcase_25 | AC | 147 ms
113,348 KB |
testcase_26 | AC | 156 ms
110,240 KB |
testcase_27 | AC | 146 ms
111,388 KB |
testcase_28 | AC | 244 ms
113,296 KB |
testcase_29 | AC | 141 ms
112,608 KB |
testcase_30 | AC | 133 ms
110,204 KB |
testcase_31 | AC | 217 ms
111,244 KB |
testcase_32 | AC | 174 ms
110,736 KB |
testcase_33 | AC | 144 ms
112,300 KB |
ソースコード
""" Mercurialist 想定解 v0.0 O(X+Y+Z) で解く X,Zは区別せず、Yだけ区別して考える。 全ての通り数は nCr(X+Y+Z,X) * nCr(Y+Z,Y) * Y! 生きている通り数を数えあげる。 i日目に最初のエリクシールが来る場合~ をi = 0 , ... ,X+Y+Z-1 まで全探索する(0-indexed) N = X+Y+Z とする。 まず、X-1 個のエリクシールをiより右の N-1-i 個の空いている日に入れる nCr (N-1-i , X-1) 通り 次に、水銀を "死亡までの日数が短い順" に位置を決めていく。 水銀の置ける箇所は… 4個置く,K=2 の場合… |ooooo -> 5*4*3*2 o|oooo -> 5*4*3*2 oo|ooo -> 5*4*3*2 ooo|oo -> 4*4*3*2 oooo|o -> 3*3*3*2 ooooo| -> 2*2*2*2 |ooooooo -> 7*6*5*4 o|oooooo -> 7*6*5*4 oo|ooooo -> 7*6*5*4 ooo|oooo -> 6*6*5*4 oooo|ooo -> 5*5*5*4 ooooo|oo -> 4*4*4*4 oooooo|o -> 3*3*3*3 ooooooo| -> 2*2*2*2 のように変化する 1 1 1 1の場合, 6通りの内 YZXだけ死ぬ 多分これでok? """ import sys from sys import stdin from collections import deque def modfac(n, MOD): f = 1 factorials = [1] for m in range(1, n + 1): f *= m f %= MOD factorials.append(f) inv = pow(f, MOD - 2, MOD) invs = [1] * (n + 1) invs[n] = inv for m in range(n, 1, -1): inv *= m inv %= MOD invs[m - 1] = inv return factorials, invs def nCr(n,r): if n < r or n < 0: return 0 return faclis[n] * invlis[n-r] * invlis[r] % mod mod = 998244353 faclis,invlis = modfac(400000,mod) def getinv(x): return pow(x,mod-2,mod) X,Y,Z,K = map(int,stdin.readline().split()) N = X+Y+Z # 0日目に最初のエリクシールが来る時の水銀の置き方を求めておく hg_place_part = 1 hg_queue = deque() for j in range(Y): hg_place_part *= N-X-j hg_place_part %= mod hg_queue.append( N-X-j ) ans_n = 0 #求める確率の分子 for i in range(X+Y+Z): #i日目が最初のエリクシールの場合 if N-1-i < X-1: break right = N-1-i #i番目よりも右のマスの数 right_notX = right - (X-1) #i番目よりも右、Xでないマスの数 hg_place = hg_place_part * pow(right_notX + K , Y-len(hg_queue) , mod) % mod ans_n += nCr(N-1-i,X-1) * hg_place ans_n %= mod #print (i,hg_queue,right_notX+K) # hg_place の更新 if i >= K and hg_queue: # <=かも? hg_place_part *= getinv( hg_queue.popleft() ) hg_place_part %= mod ans_d = nCr(X+Y+Z,X) * nCr(Y+Z,Y) * faclis[Y] % mod print (ans_n,file=sys.stderr) print (ans_n * getinv(ans_d) % mod)