Processing math: 23%

AtCoder Beginner Contest 246 Ex問題メモ

Ex - 01? Queries

問題

  • '0','1','?' の3種の文字のみからなる長さ N の文字列 S が与えられる
  • Q 個のクエリを順番に処理せよ
  • クエリ
    • xi,ci が与えられる
    • Sxi 文字目を ci('0','1','?' のいずれか)に書き換える
      • この変更は以降のクエリにも反映される
    • S に含まれる全ての '?' を '0' または '1' に独立に置き換えて得られる文字列の、(連続とは限らない)部分列」としてあり得る文字列の個数を \mod{998244353} で出力する
  • 1 \le N,Q \le 10^5
  • 実行時間制限: 6sec.

解法

DPの遷移が、小さな行列の積で表現できることを利用して、行列を乗せたセグメント木で必要な箇所だけを更新する。

公式Editorialでは3×3の行列を用いていた。その方が自然なので、基本的にそちらを参照すればよい。

4×4の行列を使って解いたので、考えだけメモ。

  • DP[i][j]=S の先頭 i 文字で作れる部分列で、(j: 後述の分類)に属するものの個数

j は、以下の4つの状態の分類とする。

  • oo: 後ろに'0'を置いても'1'を置いても、先頭 i 文字からは作れない部分列となる
  • ox: 後ろに'0'を置いたら新しい部分列となるが、'1'を置いた部分列は先頭 i 文字からも作れる
  • xo: 後ろに'1'を置いたら新しい部分列となるが、'0'を置いた部分列は先頭 i 文字からも作れる
  • xx: 後ろに'0'を置いても'1'を置いても、先頭 i 文字から既に作れる部分列となる

それぞれの状態から、Si+1 文字目が '0','1','?' のそれぞれの場合だったときに、 「それを末尾に採用したとき(採用したら新しい文字列となる場合のみ)」「採用しなかったとき」で、遷移先が一意に定まる。

   0                1                ?                    遷移先
   oo ox xo xx      oo ox xo xx      oo ox xo xx          ------→
oo [1, 0, 1, 0],    [1, 1, 0, 0],    [2, 0, 0, 1],    遷|
ox [1, 0, 0, 1],    [0, 1, 0, 0],    [1, 0, 0, 1],    移|
xo [0, 0, 1, 0],    [1, 0, 0, 1],    [1, 0, 0, 1],    元|
xx [0, 0, 0, 1],    [0, 0, 0, 1],    [0, 0, 0, 1],      ↓

大まかには、「先頭 i 文字から作れる部分列の集合」を B_i として、

  • S_{i+1} を末尾に採用して新規部分列としたら、その後ろに何かをさらにくっつけた部分列は B_{i+1} には含まれないので、ooに遷移できる(遷移元の状態問わず)
    • たとえば B_i に '00' が含まれ、S_{i+1}=1 を追加して新規部分列 '001' が作れるとなったとき、B_{i+1} に '0010' や '0011' が既に含まれる、という状態なら、B_i の時点で '001' が既に含まれていないとおかしいので矛盾
  • S_{i+1} を採用できるのに採用しなかったら、採用したものも B_{i+1} に含まれるので、次からは採用できなくなる
    • S_{i+1}=0 のとき、oo なら xo に遷移、ox なら xx に遷移、など

あとは S の各文字に対応する行列を先頭からかけ算していった結果で、1行目の和が答えとなる(初期状態の空文字列は oo にあたるので)。
ただし結果には空文字列も含まれるため、最後に -1 する。

セグメント木の実装に注意。行列積は左項と右項の順番で答えが変わるので、ここを蔑ろにした実装では正しい答えが求まらない。

行列積の計算量はサイズの3乗で利いてくるので、3^3=274^3=64 では2倍以上効率が悪いが、Pythonでもギリギリで通った。

Python3

programming_algorithm/contest_history/atcoder/2022/0402_abc246.txt · 最終更新: 2022/04/07 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0