Handstand
ABC124-D "Handstand"
(解説見ちゃった)
提出コード
考察
愚直に(解法)
左端を固定()して,番目以降ののまとまりを順に回だけに変換していきます.
その中で,連続するの数の最大値を更新していけばOK.
例えば,サンプルを取り上げます.
11101010110011
・ のとき
11101010110011
回まで操作が許されているので,のまとまりを番目以降の左から順ににします.
操作前:11101010110011
操作後:11111110110011
・ のとき
11101010110011
回まで操作が許されているので,のまとまりを番目以降の左から順ににします.
操作前:11101010110011
操作後:11101011111111
これををからまで動かしての連続する数の最大を取ることで答えは出ます.
でもこれはなのでTLEします.
累積和っぽいやり方(解法)
が切り替わる場所をborder[ ]に記録してみます.
border[ ]
これを前計算しておいて,あとは左端(番目)を順に見ていき,番目以降のの塊を回だけにしていきます.
実は左端は全探索する必要はないです.
なぜなら,例えばサンプルではよりの方が明らかに左端として最適だからです.
つまり,連続するまたはのうち左端のみを全部見ていけばOKです.
左端がかかで状況は違います.
・左端がのとき.
下の図のうち,上の段は入力列,下の段は入力列に対応するborder[ ]の中身が入っています.
そして,左端がの状況を考えてみます.
ここでは,回まで操作を行えるので,の塊の位置を回分飛ばすと見なして青矢印の終点位置にたどり着きます.
(累積和の性質上,たどり着く位置を一つ右にずらしています.)
の塊を回飛ばすとは回変化します.
よって,サンプルでは回飛ばせるので,最終位置は初期位置からだけ右にずれることがわかります.
ここで,この青矢印の始点と終点の位置でborder [ ]を使ってあげると,
border[ ] - border [ ]
個の連続したを並べることが可能です.
ただし,右にずれた結果が入力長からはみ出した場合は,border [ ]の値はとします.
イメージでは,番目以降で連続したを最大で個並べられるということです.
・左端がのとき
左端がのときは,左端からだけ右にずれることができましたが,左端がのときはだけです.
右にずれた結果が入力長からはみ出すので,計算は
border [ ]
です.(下図)
これらを一般化します.
まずはborder [ ] を作り,入力列を左端から順に見ていきます.
番目がならば,border [ ] border [ ]を計算.
番目がならば,border [ ] border [ ]を計算.
ただし,上でも触れたように,右にずれた結果が入力長からはみ出した場合は,border [ ]の値はとします
これの最大値を順次更新していけばOKです.
感想
累積和の応用ってかんじですね.
累積和は基本的な問題しか解いたことなかったので,こういう使い方があるんやーって勉強になりました.
類題は解けるようになりたい...
そろそろ卒論に拍車をかけないといけないので競プロの精進は一気に落ちそうです.
恐らく年内にもう1問できたらいいなーぐらいで,1月は2問できるかできないかという予想です.
ワンチャン,良いお年を.