トピック:https://loj.ac/problem/2304
説明のさまざまなを読む......
\(DP [I] [J] \)は、i行、j番目の行及び次のデフォルトの方法、少なくともグリッド、矩形領域が<= LM最大法的を満たすことJ + 1行不正確率を表します。j番目の行と次の貢献は、Q 1の代わりに、いくつかの当事者の一部です。
那么有\(DPは[I] [j]はDPを= [I]、[J + 1] * P ^ I + \和\ limits_ {k = 1} ^ {I} DP [K-1] [J + 1] * P ^ {K-1} *(1-P)* DP [IK] [J] \)
i>が一番下の行は、少なくとも1つの位置を持つ必要があり、kは、違法であるときことに留意されたいです。そう順序\(ans_i \は、i)の確率は\(ans_i = \和\ limits_ {J = 1} ^ {I} ans_ {J-1} *(1-P)* DP [IJ] [1でカラムを番目表します] * P ^ {IJ} \)
\(Ans_i \)DPの初期値である[I] [0]。DPを注意[0] [*] = 1。その後、知識の最適化の定数係数線形均質再発を使用することができます。
空の配列に注意してください。本当に取り払うnの値に注意を払ってはいけません。
書式#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define LL長い長い 使って 名前空間はstdを、 const int型 N = 1005、M = N << 1、MOD = 998244353 。 INT UPT(INT X){ 一方(X> = MOD)X- = MOD。一方、(x < 0)、X + = MOD。戻りX;} int型 PW(int型のx、int型K) { int型 RET = 1。一方、(K){ 場合(K&1)RET =(LL)RET * X%MOD; X =(LL)X * X%MOD; kは>> = 1 ;} リターンRET;} int型N、Q、Q2、F [N] [N]、ビン[N]、[N]、ANS [M]、B [M]、C [M]、LM。 ボイドムル(INT * U、INT * V)// (LM-1)」 { memsetの(C、0、はsizeofのC)。 以下のために(int型 i = 0 ; iはLMを<; I ++ ) のための(INT J = 0 ; J <LM; J ++ ) C [iが + J] =(C [iが+ J] +(LL)のu [i]は* V [J])%MOD。 以下のために(int型私は= 2 *(LM- 1を); I> = LM; i-- ) 場合(C [i]が) のための(INT J = 1 ; J <= LM; J ++ ) C [I -j] =(C [IJ] +(LL)C [ I] * [J])%のMOD。 memcpy(U、C、はsizeof 4 *のLM)。// 0〜LM-1 } int型解く(INT TMP) { LM = TMP。memsetの(F、0、はsizeof F)。 用(INT J = 0 ; J <= LM + 1 [F J ++;)0 ] [J] = 1。// LM + 1 LMではありません! にとって(int型 = Iを1 ; I <= LM; I ++ ) のための(INT J = LM / I、J> = 0 ; j-- ) { int型 TP =(LL)[I] [J + F 1 ] *ビン[I 】%MOD。 用(int型のk = 1 ; K <= iは、++ k個) { int型ミリリットル=(LL)を[K-F 1 ] [J + 1 ] * F [IK] [J]%MOD。 ミリリットル =(LL)ミリリットル* Q2の%MOD *ビン[K- 1 ]%MOD。 TP = UPT(TP + ミリリットル)。 } F [I] [J] = TPと、 } もし(N <= LM)リターン [N] F [ 0 ]。LM ++ ; 以下のために(int型 I = 1 ; I <= LM; iは++ ) { int型 TP =(LL)[I-F 1 ] [ 1 ] *ビン[I- 1 ]%MOD。 [I] =(LL)TP * Q2の%のMOD。// ないLM-I } のmemset(ANS、0、はsizeof ANS)。/// / memsetの(B、0、はsizeofの B)。/// / ANS [ 0 ] = bの[ 1 ] = 1; INT TN = N。////// 一方(TN) { 場合(TN&1)ムル(ANS、B)。MUL(B、B)。TN >> = 1 ; } INT RET = 0 。 用(int型 I = 0 ; iがLM <; I ++の) RET =(RET +(LL)ANS [I] * [I] F [ 0 ])%MOD。 リターンRET; } int型のmain() { int型、X、Y、K; scanf関数(" %D%D%D%D "、&N&K、およびX&Y)。 Q =(LL)X * PW(Y、mod- 2)%のMOD。Q2 = UPT(1 - Q); ビン[ 0 ] = 1 。 以下のために(int型私= 1 ; iが= Kを<; I ++)はビン[I] =(LL)ビン[I- 1 ] *のQ%のMOD。 printf(" %Dを\ n "、UPT(解く(k)は-solve(K- 1 )))。 リターン 0 ; }