LOJ 2304「NOI2017」プール - アイデア+ DP +定数係数の線形均質な再発

 

トピック: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 ; 
}

 

おすすめ

転載: www.cnblogs.com/Narh/p/10993097.html