結果
| 問題 |
No.1547 [Cherry 2nd Tune *] 偶然の勝利の確率
|
| コンテスト | |
| ユーザー |
👑 Kazun
|
| 提出日時 | 2024-02-25 00:25:19 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 314 ms / 2,000 ms |
| コード長 | 9,265 bytes |
| コンパイル時間 | 287 ms |
| コンパイル使用メモリ | 81,792 KB |
| 実行使用メモリ | 77,824 KB |
| 最終ジャッジ日時 | 2024-09-29 10:28:22 |
| 合計ジャッジ時間 | 6,772 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 36 |
ソースコード
from copy import deepcopy
class Modulo_Matrix():
__slots__=("ele","row","col","size")
#入力
def __init__(self,M):
""" 行列 M の定義
M: 行列
※ Mod: 法はグローバル変数から指定
"""
self.ele=[[x%Mod for x in X] for X in M]
R=len(M)
if R!=0:
C=len(M[0])
else:
C=0
self.row=R
self.col=C
self.size=(R,C)
#出力
def __str__(self):
return "["+"\n".join(map(str,self.ele))+"]"
def __repr__(self):
return str(self)
# 零行列, 単位行列
@classmethod
def Zero_Matrix(cls, row, col):
return Modulo_Matrix([[0] * col for _ in range(row)])
@classmethod
def Identity_Matrix(cls, N):
return Modulo_Matrix([[1 if i==j else 0 for j in range(N)] for i in range(N)])
#+,-
def __pos__(self):
return self
def __neg__(self):
return self.__scale__(-1)
#加法
def __add__(self,other):
M=self.ele; N=other.ele
L=[[0]*self.col for _ in range(self.row)]
for i in range(self.row):
Li,Mi,Ni=L[i],M[i],N[i]
for j in range(self.col):
Li[j]=Mi[j]+Ni[j]
return Modulo_Matrix(L)
def __iadd__(self,other):
M=self.ele; N=other.ele
for i in range(self.row):
Mi,Ni=M[i],N[i]
for j in range(self.col):
Mi[j]+=Ni[j]
Mi[j]%=Mod
return self
#減法
def __sub__(self,other):
M=self.ele; N=other.ele
L=[[0]*self.col for _ in range(self.row)]
for i in range(self.row):
Li,Mi,Ni=L[i],M[i],N[i]
for j in range(self.col):
Li[j]=Mi[j]-Ni[j]
return Modulo_Matrix(L)
def __isub__(self,other):
M=self.ele; N=other.ele
for i in range(self.row):
Mi,Ni=M[i],N[i]
for j in range(self.col):
Mi[j]-=Ni[j]
Mi[j]%=Mod
return self
#乗法
def __mul__(self, other):
if isinstance(other, Modulo_Matrix):
assert self.col == other.row, f"左側の列と右側の行が一致しません (left: {self.col}, right:{other.row})."
A = self.ele; B = other.ele
C = [[0] * other.col for _ in range(self.row)]
for i in range(self.row):
Ai = A[i]
Ci = C[i]
for k in range(self.col):
a_ik = Ai[k]
Bk = B[k]
for j in range(other.col):
Ci[j] = (Ci[j] + a_ik * Bk[j]) % Mod
return Modulo_Matrix(C)
elif isinstance(other,int):
return self.__scale__(other)
def __rmul__(self,other):
if isinstance(other,int):
return self.__scale__(other)
def inverse(self):
assert self.row==self.col,"正方行列ではありません."
M=self
N=M.row
R=[[1 if i==j else 0 for j in range(N)] for i in range(N)]
T=deepcopy(M.ele)
for j in range(N):
if T[j][j]==0:
for i in range(j+1,N):
if T[i][j]:
break
else:
assert 0, "正則行列ではありません"
T[j],T[i]=T[i],T[j]
R[j],R[i]=R[i],R[j]
Tj,Rj=T[j],R[j]
inv=pow(Tj[j], -1, Mod)
for k in range(N):
Tj[k]*=inv; Tj[k]%=Mod
Rj[k]*=inv; Rj[k]%=Mod
for i in range(N):
if i==j: continue
c=T[i][j]
Ti,Ri=T[i],R[i]
for k in range(N):
Ti[k]-=Tj[k]*c; Ti[k]%=Mod
Ri[k]-=Rj[k]*c; Ri[k]%=Mod
return Modulo_Matrix(R)
#スカラー倍
def __scale__(self,r):
M=self.ele
r%=Mod
L=[[(r*M[i][j])%Mod for j in range(self.col)] for i in range(self.row)]
return Modulo_Matrix(L)
#累乗
def __pow__(self, n):
assert self.row==self.col, "正方行列ではありません."
sgn = 1 if n >= 0 else -1
n = abs(n)
C = Modulo_Matrix.Identity_Matrix(self.row)
tmp = self
while n:
if n & 1:
C = C * tmp
tmp = tmp * tmp
n >>= 1
return C if sgn == 1 else C.inverse()
#等号
def __eq__(self,other):
return self.ele==other.ele
#不等号
def __neq__(self,other):
return not(self==other)
#転置
def transpose(self):
return Modulo_Matrix(list(map(list,zip(*self.ele))))
#行基本変形
def row_reduce(self):
M=self
(R,C)=M.size
T=[]
for i in range(R):
U=[]
for j in range(C):
U.append(M.ele[i][j])
T.append(U)
I=0
for J in range(C):
if T[I][J]==0:
for i in range(I+1,R):
if T[i][J]!=0:
T[i],T[I]=T[I],T[i]
break
if T[I][J]!=0:
u=T[I][J]
u_inv=pow(u, -1, Mod)
for j in range(C):
T[I][j]*=u_inv
T[I][j]%=Mod
for i in range(R):
if i!=I:
v=T[i][J]
for j in range(C):
T[i][j]-=v*T[I][j]
T[i][j]%=Mod
I+=1
if I==R:
break
return Modulo_Matrix(T)
#列基本変形
def column_reduce(self):
M=self
(R,C)=M.size
T=[]
for i in range(R):
U=[]
for j in range(C):
U.append(M.ele[i][j])
T.append(U)
J=0
for I in range(R):
if T[I][J]==0:
for j in range(J+1,C):
if T[I][j]!=0:
for k in range(R):
T[k][j],T[k][J]=T[k][J],T[k][j]
break
if T[I][J]!=0:
u=T[I][J]
u_inv=pow(u, -1, Mod)
for i in range(R):
T[i][J]*=u_inv
T[i][J]%=Mod
for j in range(C):
if j!=J:
v=T[I][j]
for i in range(R):
T[i][j]-=v*T[i][J]
T[i][j]%=Mod
J+=1
if J==C:
break
return Modulo_Matrix(T)
#行列の階数
def rank(self):
M=self.row_reduce()
(R,C)=M.size
T=M.ele
rnk=0
for i in range(R):
f=False
for j in range(C):
if T[i][j]!=0:
f=True
break
if f:
rnk+=1
else:
break
return rnk
# 単射 ?
def is_injection(self):
return self.rank() == self.col
# 全射 ?
def is_surjective(self):
return self.rank() == self.row
# 全単射 ?
def is_bijection(self):
return self.col == self.row == self.rank()
#行の結合
def row_union(self,other):
return Modulo_Matrix(self.ele+other.ele)
#列の結合
def column_union(self,other):
E=[]
for i in range(self.row):
E.append(self.ele[i]+other.ele[i])
return Modulo_Matrix(E)
def __getitem__(self,index):
if isinstance(index, int):
return self.ele[index]
else:
return self.ele[index[0]][index[1]]
def __setitem__(self,index,val):
assert isinstance(index,tuple) and len(index)==2
self.ele[index[0]][index[1]]=val
#========================
#===入力
MA,NA,S=map(int,input().split())
MB,NB,T=map(int,input().split())
K=int(input())
#===定数の設定
Mod=998244353
rho_A=(MA*pow(NA,Mod-2,Mod))%Mod
rho_B=(MB*pow(NB,Mod-2,Mod))%Mod
#===Aについての行列
U=[[0]*(S+T+1) for _ in range(S+T+1)]
for y in range(S+T+1):
for x in range(S+T+1):
if x==0:
U[y][x]=1 if y==0 else 0
elif x==S+T:
U[y][x]=1 if y==S+T else 0
else:
if y<x:
U[y][x]=0
else:
if y==S+T:
U[y][x]=pow(rho_A,y-x,Mod)
else:
U[y][x]=(pow(rho_A,y-x,Mod)*(1-rho_A))%Mod
#===Bについての行列
V=[[0]*(S+T+1) for _ in range(S+T+1)]
for y in range(S+T+1):
for x in range(S+T+1):
if x==0:
V[y][x]=1 if y==0 else 0
elif x==S+T:
V[y][x]=1 if y==S+T else 0
else:
if y>x:
V[y][x]=0
else:
if y==0:
V[y][x]=pow(rho_B,x-y,Mod)
else:
V[y][x]=(pow(rho_B,x-y,Mod)*(1-rho_B))%Mod
#===行列の計算
E=pow(Modulo_Matrix(V)*Modulo_Matrix(U),K)
#===結果の出力
print(E[S+T,T])
print(E[0,T])
Kazun