B - Near Assignment Editorial by maroonrk_admin
\(A=B\) の場合は明らかに可能なので,それ以外のケースを考えます.
\(K\) の値で場合分けします.
\(K=1\) のケース:
\(A\)の要素をランレングス圧縮した結果を考えると,操作によって”減る”ことはあっても”増える”ことはありません. ここから得られる条件として,\(B\) をランレングス圧縮した結果が \(A\) の部分列である必要があるとわかります. そしてこれは十分です. \(B\) に対応する \(A\) の部分列を伸ばしていく操作を行えば良いからです. これで \(K=1\) のケースは解けました.
\(K \geq 2\) のケース:
操作を逆から見ると,以下のようになります.
- \(|i-j| \leq K,B_i=B_j\) を満たす \(i,j\) を選び,\(B_i\) を好きな値に変更する.
まず,\(B\) に一度も操作を行えない場合,答えは No
です.
また,\(B\) に登場するが \(A\) に登場しない値がある場合も答えは No
です.
実はこれ以外のケースはすべて Yes
です.
\(B_i\) を好きな値にする,という部分を,\(B_i\) をワイルドカード \(*\) に変更するという操作で捉え直しましょう. \(B\) に \(1\) 回操作を行うことで,\(*\) が \(1\) つ存在する状態にしておきます.
\(*\) を絡めることで,\(B\) の隣接要素の swap が実現できます.
- \(*x\) を \(x*\) にしたい場合: \(*x\) を \(xx\) だと思って操作すれば \(x*\) にできる.
- \(*xy\) を \(*yx\) にしたい場合: \(*xy \to yxy \to yx* \to y*x \to *yx\) とすればよい.
以上の操作を組み合わせると,\(B\) の要素の重複をすべて削除し,かつ好きな順序で並べることができます. 特に,\(B\) が \(A\) にマッチするようにできます. よって \(A\) を \(B\) に変形できるとわかります.
以上の操作をそのまま実装すると \(O(N)\) 解法が得られます. なお,回答例はサボってソートを行っているため \(O(N\log N)\) 解法になっています.
posted:
last update: