結果
| 問題 | No.2468 Mercurialist |
| コンテスト | |
| ユーザー |
👑 SPD_9X2
|
| 提出日時 | 2023-05-09 07:50:28 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 300 ms / 2,000 ms |
| コード長 | 2,598 bytes |
| コンパイル時間 | 280 ms |
| コンパイル使用メモリ | 82,168 KB |
| 実行使用メモリ | 113,704 KB |
| 最終ジャッジ日時 | 2024-11-20 18:57:13 |
| 合計ジャッジ時間 | 6,901 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 30 |
ソースコード
"""
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)
SPD_9X2