ABC202 D - aab aba baa 別解
ABC202 D - aab aba baaの桁DP+二分探索を用いた解法の解説です.
問題概要
個のa
と個のb
からなる長さの文字列のうち,辞書順で番目のものを求めてください.
制約
・
・個のa
と個のb
からなる長さの文字列が少なくとも個は存在することが保証される
解法
a
を,b
をに直します.すると,a
とb
からなる文字列は2進数とみなすことができます.
この操作をしたあと,元の問題は「が回使われている2進数の小さいほうから番目の数は何か」と言い換えることができます.
桁に満たないものは桁になるまで先頭にをつけ足せばが個という条件を満たします.また,同じ桁数同士の整数の大小関係はそれを文字列として見たときの辞書順の大小関係と一致します.よって,上の言い換えが成立することがわかります.
次に以下の小問題を考えます.
・2進法表記された整数以下にが回使われている数は個未満かどうか
であって,十分大きな整数に対してはです.また,がとなるならばを満たす任意のに対してです.同様に,がとなるならばを満たす任意のに対してです.よってこの小問題には単調性があり,あるが存在してとなります.この時のが答えとなります.
小問題の判定について考えてみましょう.「〇〇以下の条件を満たすものの個数」という問題は桁DPというアルゴリズムを用いて求めることができる場合が多く,今回もそれを用いて判定することを考えます.
配列の定義
上から桁目まで見て,の個数が個で,より小さいことが確定しているかどうか(がならちょうど,ならより小さいことが確定)
遷移
・からはにのみ遷移
・からに遷移
・からに遷移
それぞれの遷移ごとにの値を増やしたりそのままにしたりして遷移します(詳しくは僕の提出を参考にしてください).
判定内容
を2進数表記して,その桁数をとすると, かどうか
以上の方法を用いて小問題を構成します.
先に述べたようにこの小問題には単調性があるので,二分探索を用いて答えとなる整数を求めることができます.最後に求めた答えを2進数に変換し,をa
に,をb
に変更した文字列が最終的な答えとなります.
小問題を回解くごとに,の桁数をとするとであり,二分探索の探索範囲をとすると小問題を回程度行うので,全体としての計算量はとなり,この問題の条件下では十分高速です.
Bonus問題
a
が個,b
が個からなる文字列が与えられます.a
が個,b
が個からなる文字列すべてのうちは辞書順で何番目か.で割ったあまりを求めよ.(要するに元の問題の逆操作です)
・