解法
DP. 状態を,\(T\) の \([0,j)\) まで一致させたとして \(j\) をもつ. \(S_{i}\) を使えるかどうかは, \(T_{[0,j)} + S_{i} = T_{[0,j+|S_{i}|)}\) と同値.
注意
substr は,範囲外にならない様に.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
DP. 状態を,\(T\) の \([0,j)\) まで一致させたとして \(j\) をもつ. \(S_{i}\) を使えるかどうかは, \(T_{[0,j)} + S_{i} = T_{[0,j+|S_{i}|)}\) と同値.
substr は,範囲外にならない様に.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
削除のみの場合. クエリを先読みして,逆に処理すれば,union-find で解ける.
追加と削除の場合. ただし,追加する辺が 10個以下.
この場合もベースになるのは Easy版で,クエリ先読みと逆順処理をする. もとのクエリで追加する辺(逆順処理では削除する辺)は少ないので, その度に union-find を構成しなおしても間に合う.
Union-find を再構成するために, 逆順で処理したときに,追加した辺を記録しておく.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
貨幣の枚数を考える. 組(金貨,銀貨,銅貨) が辞書順で最大になるのがベスト. 銅貨の残り枚数を状態にもって DP すれば O(NX).
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
何を全探索するか考える. 素直に \(T\) を全探索するのでは \(TLE\) . \(T\) は全探索できないが,\(T\) の \(?\) の位置は,最大で \({}_{10}C_{5} = 252\)なので十分間に合う.
まず \(S := S_{i}\) を一つ固定して考える. \(?\) の位置だけ固定したとき, \(S\) から \(T\) を作れる条件を考える. \(j \in T.size()\) において,
よって, 全ての \(j \in |T|\) with \(T_{j} = '?'\) と なる \(j\) に対して \(S_{j}\) を \('?'\) で置き換えて, \(S = T\) となることが,\(S\)から \(T\) を作れる必要条件. これが十分条件であることは明らか.
次に \(i \in N\) を動かして考えてみるが, これは全体で \(O({}_{L}C_{L/2} N)\) となる. ただし,\(S_{i}\) の一部を \(?\) で置き換えた文字列の個数をカウントするときに map を使っているので,オーダーに \(max_{i \in N} (|S|) log N\) が掛かる.
\(?\) の取り方は bitmask を用いると簡単. \(?\) の選び方 \(\in 2^{L}\) のうち,popcount が \(K\) の物だけ使えばよい.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
ダメージの累計が最小になる様に手裏剣を使う.
いくつか思いつくことがある.
それぞれについて詳しく見ていく.
敵が 1体のとする.手裏剣を \(u\) 枚使ったとする.
まとめると, \(x = 1\)のときは基本的に手裏剣 1枚目だけダメージが \(2a\) 得するが, \(b = 1\) のときは \(a\) 得する. \(1\) 枚投げれば,\(x = 0\) に帰着できる. \(x = 0\)のときは,1枚につき \(a\) 得する.
また,手裏剣を 0枚使ったときの暫定的な答えはすぐに求まる.
\(x = 1\) かつ \(b = 1\) のときは,手裏剣を \(1\)枚投げても \(a\) しか得をしない.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
\(A\) が \(B\) より強いと分かっているとき,かつそのときに限り \(A\) から \(B\) に矢を張ったグラフ \(G\) を考える.
辞書順を無視して,強い順に並べる. これは \(G\) においてトポロジカルソートするのと同じ.
辞書順最小の,強い順に並べる. トポロジカルソートで頂点を並べるとき, 選ぶ頂点の候補が複数あれば最小の物を選ぶようにすればよい. これは,入次数 0 の頂点を入れる入れ物として, min priority queue を用いれば良い.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
コストの最小を求めるが,下界を求めてそれを実現する例を与える. 下界を求める過程は,必要条件を求めるのに近い.
コストを無視して \(P_{i}\) と \(P_{i+1}\) の swap を考える. \(P\) を昇順にするには,小さい \(P_{i}\) から左に寄せていくと, 少ない回数でソートできる.
コストがある場合も,コスト無しの場合と似た方法で出来る. \(P_{[0,i)}\) までソートされているとして,\(i = P_{i}\) となるように並べ替えることを考える. このとき,最低でも掛かるコストを求める. 集合\(X\)を, \(i\) の左にある \(P\) の元のうち,\(i\) より大きい元全体 とする. \(i = P_{i}\) となるまで並べ替えるためには,最低 $$ \sum_{x \in X} (i + x) = |X|\cdot i + \sum X $$ かかる. 実際にこのコストでのソートが実現できるのは,コスト無し版の解法から分かる.
この解法には,次が有れば十分. 任意の \(i \in N\) に対して,
これらは,共に segtree で実現出来る.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"