−目次
Toyota Programming Contest 2024#1(AtCoder Beginner Contest 337)F問題メモ
F - Usual Color Ball Problems
問題
- 個のボールが1列に並び、それぞれの色は
- 個の、1つにつきボールを 個まで入れられる空の箱がある
- について、以下を求めよ
- ボールを、 番目が先頭になるように並べなおす。 番目のボールはそのままの順番で末尾にもっていく
- 先頭から順に、以下の要領でボールを箱に入れる(または捨てる)
- ボールの色を として、既に色 が入っていて 個未満の箱があれば、そこに入れる
- なければ、空の箱があれば適当に1つ選んで入れる
- それもなければ捨てる
- 最終的に、箱に入ったボールの個数を求めよ
解法
の時を求めて、1つずらすだけだとほとんどは同じ状態になるだろうので、 の答えは差分で計算したい。
しかし、実際に箱に入るボールは列中で飛び飛びに現れるので、 区間を1つずらしたときに、どの色の箱が無くなり、どのボールが新たな箱を作るのか、結構変化してしまい、効率的に管理しづらい。。
M=3 K=2 Ci 1 2 3 5 2 5 4 箱に入る? o o o x o x x Ci 2 3 5 2 5 4 1 箱に入る? o o o o o x x Ci 3 5 2 5 4 1 2 箱に入る? o o o o x x o Ci 5 2 5 4 1 2 3 箱に入る? o o o o x o x
重要な考察として、最終的に色 のボールが箱に入る個数というのは、以下の小さい方になる。
(これに気付かないと進めないのに、なかなか気付きづらい……)
- 色 のボールが入った箱数
- 色 のボールの個数
なので、先頭からボールを入れていくようにシミュレーションする際、 「全ての箱の色が確定したタイミング」、つまり「最後の箱に、1個ボールが入ったタイミング」で、 全体の箱に入ったボールの個数が確定するので、打ち切ってよい。
そこまでのボールは、必ず何かしらの箱に入っていることが保証される。
飛び飛びでは無くなるので、 をずらすたび、途中から探索を行える。
Ci 1 2 3 5 2 5 4 箱に入る? o o o - - - - ^ : 最後の箱にボールが入ったタイミング ^ - : 未調査 Ci 2 3 5 2 5 4 1 箱に入る? o o o - - - - ^ Ci 3 5 2 5 4 1 2 箱に入る? o o o - - - - ^ Ci 5 2 5 4 1 2 3 箱に入る? o o o o - - - ^
尺取法の要領で、区間の左右端のポインタを管理しておき、区間を1つずらした時、
- 左端のボールを取り除く。取り除いた前後で箱が1つ減れば、差分更新する
- それによって箱が1つ空になった場合、右端からボールを追加していく。次に新たに箱が作られたら差分更新し、終わる
高々2色について、答えを更新すればよい。