A - Reverse A…B 解説
by
nok0
初めに解説で使う記法を定義します.
- 文字列 \(S\) が \(T\) より辞書順で小さいもしくは等しいとき,\(S\leq T\) と書く.
- 文字列 \(S\) 全体を反転して得られる文字列を \(\mathrm{rev}(S)\) と書く.
- \(S\) の \(l\) 文字目から \(r\) 文字目までからなる部分文字列を \(S[l:r]\) と書く.
\(X\) を \(Y\) にできる必要十分条件は以下です.
- \(X\) と \(Y\) に含まれる A の個数が等しい
- \(X\leq Y\)
- \( \mathrm{rev}(Y)\leq \mathrm{rev}(X)\)
上が必要条件であることは明らかです.十分条件であることを実際の構築手法を提示することで示します.
\(X_1, X_N, Y_1, Y_N\) がそれぞれ A, B, B, A で,かつ \(X\) と \(Y\) の A の個数が等しい場合を考えます.
途中で \((l, r) = (1, N)\) の操作を必ず挟むようにします.これより前の操作を \(\mathrm{op\_front}\),後の操作を \(\mathrm{op\_back}\) とします.
ここで,\(\mathrm{op\_back}\) を \(Y\) に対する操作とみなすことにします.\(\mathrm{op\_back}\) を逆順に見ると,
- \(Y_l, Y_r\) が
B,Aであるような \((l, r)\) に対し,\(Y[l:r]\) を反転させる
に対応します.
\(X\) に対して \(\mathrm{op\_front}\) と \((1,N)\) をこの順に行って得られる文字列を \(X'\) ,\(Y\) に対して\(\mathrm{op\_back}\) の逆順に操作を行って得られる文字列を \(Y'\) とすれば,\(X'=Y'\) です.
\(S\) を \(X[2:N-1]\),\(T\) を \(Y[2:N-1]\)を 反転 させた文字列とすると,以下の問題と等価になります.
- 以下の操作を合計で高々 \(\frac{N-2}{2}\) 回行って,\(S=T\) にせよ.
- \(S_l, S_r\) が
A,Bであるような \((l,r)\ (1\leq l\lt r\leq N-2)\) を選び,\(S[l:r]\) を反転する - \(T_l, T_r\) が
A,Bであるような \((l,r)\ (1\leq l\lt r\leq N-2)\) を選び,\(T[l:r]\) を反転する
- \(S_l, S_r\) が
\(1\) 種類目の操作を操作順に並べた列が \(\mathrm{op\_front}\),\(2\) 種類目の操作を操作の 逆順 に並べた列が \(\mathrm{op\_back}\) に対応します.
上の問題を考えます.\(S\) に含まれる A の個数が B の個数より少ない場合を考えます.\(S,T\) における A の出現位置を昇順に並べた列を \(p,q\) とします.\(i = |p|, |p|-1, \dots,1\) の順に以下を行うことで \(S=T\) にすることができます.
- \(p_i=q_i\) のとき:なにもしない
- \(p_i\lt q_i\) のとき:\(l=p[i],r=q[i]\) として \(S[l:r]\) を反転する.
- \(p_i\gt q_i\) のとき:\(l=q[i],r=p[i]\) として \(T[l:r]\) を反転する.
\(|p|\leq \frac{N-2}{2}\) なので,操作回数は \(\frac{N-2}{2}\) 回以下です.A の方が多く含まれる場合も同様の方法で \(\frac{N-2}{2}\) 回以下の操作で目標を達成できます.
投稿日時:
最終更新: