解説:Circulating Stones
石が 2 個以上ある箱を見つけるたびに操作しても、目標の配置に近づいているとは限りません。 また、入力例 3 では一つの箱を 5 億回操作するので、手順を一回ずつ求める方法も使えません。
そこで、まず操作の順番を考えずに「各箱を何回操作するか」を求めます。 その回数を高さとして並べると、山のような形ができます。 あとは、この山をどの順番で削れば、途中で石が足りなくならないかを考えます。
箱の番号は問題文と同じく とします。 添字は円周上で考え、例えば 、 と読み替えます。
1. 各箱の操作回数を求める
箱 を 回操作するとします。 自分の操作で石が 個減り、両隣の操作で 個増えるので、目標の配置にするためには
が必要です。 この式が合っていても、操作の途中で石が足りなくなるかもしれません。 その点はいったん置いて、まず整数の回数が存在するかを調べます。
操作によって石の総数は変わりません。 なら、この時点で不可能です。 以下では総数が等しいとします。
回数そのものより、隣同士の差を見る
、 と置くと、式 (1) は
となります。したがって、最初の差 さえ分かれば、残りの差も順に求まります。
と置くと、
一周したときの高さの変化は 0 なので、 です。よって
と決まります。右辺が整数でなければ、整数の操作回数は存在しません。
整数であれば、まず とし、 によって全体を復元します。 このとき、円のつなぎ目でも式が成り立つことを確認しておきます。 より であり、 より です。 したがって、この復元で式 (1) をすべての箱について満たせます。
山の最も低いところを 0 に合わせる
式 (2) によって、隣り合う箱の回数の差はすべて決まっています。 そのため、式 (1) の解同士は、全成分に同じ定数を加えたものに限られます。 逆に、全成分に同じ定数を加えても式 (1) は変わりません。
復元した は負の成分を持つことがあるので、全成分から最小値を引きます。 こうして得た列を とします。
を高さとして描いたものを、ここでは「回数の山」と考えます。 この山は、最も低いところが基準線 に接しています。
非負整数の解はすべて
と書けます。つまり、どんな手順を使うとしても、箱 は少なくとも 回操作する必要があります。 まだ、この最小の回数だけで実際に操作できるとは限りません。それができる条件を、ここから考えます。
ただし、 がすべて 0 なら、式 (1) より既に です。 この場合はブロック数 0 を出力して終了します。以下では の場合を考えます。
2. 最後に操作する順番を考える
操作を始める側から考えると、箱を選ぶたびに石の個数が変わってしまいます。 そこで、目標の配置に到達できたとして、各箱を最後に操作した時刻に注目します。
と置きます。式 (3) より、 に入っている箱は、どんな成功する手順でも必ず一度以上操作されます。 の箱を余分に操作する手順もあり得ますが、ここでは の箱の最後の操作だけを見ます。
の箱を、最後の操作が早い順に並べてみましょう。 箱 を最後に操作した後は、この箱の石が減ることはありません。 最後の操作の直後にも、石の個数は 0 以上です。 また、この順番で より後ろにある隣の箱からは、その箱の最後の操作によって少なくとも 1 個の石が届きます。 したがって、
は、順番が より後ろにある隣の箱の数以上でなければならない。
という条件が必要です。
この条件を満たす順番を求める
まだ順番を決めていない箱の集合を とします。 箱 の両隣のうち、 に含まれる箱の数を と書きます。
最初は とし、
を満たす箱 を選んで、順番の末尾に追加し、 から除きます。 ここで除くのは順番を管理するための集合からだけで、石の配置はまだ変えません。
条件を満たす箱が複数あれば、どれを選んでも構いません。 実際、一つの箱を除くと、ほかの箱の は減ることはあっても増えません。したがって、除く前に式 (4) を満たしていた箱が、除いたことで条件を満たさなくなることはありません。
また、成功する操作列があると仮定すると、 が空でない限り、その操作列で「 の中で最後の操作が最も早い箱」 は式 (4) を満たします。 内の隣の箱はすべて より後に最後の操作を行うからです。 よって、成功する操作列があるなら、この手続きが途中で止まることはありません。
したがって、箱が残っているのに一つも選べなくなった場合は不可能です。 の箱をすべて取り除けた場合は、その順番を とします。 ここまでで分かったのは必要性です。次に、 が得られれば本当に構築できることを示します。
なお、順番の計算にはキューを使えます。 最初に式 (4) を満たす箱を入れておき、箱を取り除くたびに両隣の を減らします。 条件を新たに満たした箱を一度だけキューに入れれば、全体で です。
3. 山を高い層から削る
順番 が得られても、そのまま一巡ずつ操作すればよいわけではありません。 例えば入力例 1 では、
で、回数の山は です。 順番 として を選べますが、最初からこの順に操作すると、箱 の操作後に箱 には石が 1 個しかなく、続けられません。
この例では、回数が多い箱 を一度操作してから、 の順に操作すれば成功します。 山で見ると、先に高さ 2 の層を削り、その後で高さ 1 の層を削ったことになります。
箱番号 1 2 3 4 5
f 0 1 2 1 0
高さ 2 ■ → 箱 3
高さ 1 ■ ■ ■ → 箱 3, 2, 4
基準線 0 ──────────────
一般の場合も、このように高い層から処理します。 高さ の層に含まれる箱の集合を
とし、 の順に、 から の箱だけを抜き出した順番で、それぞれ一回ずつ操作します。 高さが大きい場合の圧縮は後で行うことにして、まず、この手順が必ず合法であることを証明します。
残りの操作回数から、現在の石の個数が分かる
箱 の残りの操作回数を 、現在の石の個数を とします。 既に行った操作の回数は なので、
この式を使うと、箱 に石が 2 個以上あるかどうかを、隣の残り回数との比較で調べられます。
一つの層を最後まで処理できることを示す
高さ の層を始める時点では、
が成り立つものとします。 最初の層 では なので、確かに成り立ちます。
この層で、次に箱 を操作するとします。 この層に含まれ、まだ操作していない箱の集合を とすると、 です。 隣の箱の残り回数は、 に含まれていれば 、含まれていなければ 以下です。
と置くと、式 (5) より
一方、 に残る隣の箱は、もとの順番 でも より後ろにあります。 を作ったときの条件から、そのような隣の箱の数は 以下です。 つまり なので、
です。よって、この操作を合法に行えます。
同じ議論を繰り返せば、この層を最後まで処理できます。 層に含まれる箱の残り回数は から へ減り、ほかの箱の残り回数は変わらないので、処理後は です。 これが次の層に対する式 (6) になります。
以上の帰納法により、すべての操作が合法です。 高さ 1 の層を終えると となり、式 (5) から が従います。
これで、回数の山が求まったときは、削除の手続きで を空にできることが、到達可能性の必要十分条件だと分かりました。 また、この構築は各箱をちょうど 回操作します。 到達可能なら、山全体を持ち上げる余分な操作を加えなくてもよいことも、ここで示せました。
4. 基準線に接していなければならない場所
ここまでの判定を、山の形として見直してみます。
削除の手続きが途中で止まったとします。 の箱が少なくとも一つあるので、残った箱が円全体を占めることはありません。 したがって、残った箱の連結成分は、それぞれ円周上の連続した区間です。
一箱だけの成分なら なので必ず削除できます。 よって、止まったときの各成分には二箱以上あり、両端の は 1、内部の は 2 です。 どの箱も式 (4) を満たさないことから、その区間では
- 両端の が 0。
- 内部の が 1 以下。
となります。さらに、残っている箱なので、区間内の はすべて正です。
逆に、 の巡回区間 が上の二条件を満たし、区間内の がすべて正だとします。 削除の手続きで の最初の一箱を取り除こうとすると、その時点では のほかの箱がすべて残っています。 端点には少なくとも一つ、内部には二つの隣の箱が残るので、どの箱も式 (4) を満たせません。 したがって、このような区間があると を空にすることはできません。
以上から、整数の回数の山 が求まった後の到達可能性は、次の条件とも同値です。
円周上の連続した 箱以上 箱以下の区間で、両端の が 0、内部の が 1 以下なら、その区間には の箱が少なくとも一つある。
目標配置がこのような区間を作るとき、回数の山は、その区間のどこかで基準線に接する必要があります。 区間全体が基準線より上に浮いていると、到達できません。
入力例 2 では です。 箱 はどちらも ですが、どちらの高さも正になっています。 この二箱が障害となるため、総数が一致し、整数の回数が求まっても、目標配置には到達できません。
この見方は判定の意味を理解するためのものです。 実装では区間をすべて調べる必要はなく、第 2 節のキューによる手続きで判定と順番の構築を同時に行えます。
5. 同じ層をまとめて出力する
残るのは、非常に高い山を一層ずつ処理しないための工夫です。 に現れる相異なる正の値を大きい順に
と並べ、 と置きます。 高さ から までの層では、含まれる箱の集合がすべて で共通です。 使う順番も からこの集合の箱を抜き出したものなので、すべて同じです。
したがって、この部分を一つのブロックにまとめられます。 第 ブロックでは、 のうち の箱を順に並べ、反復回数を として出力します。 圧縮しているだけなので、第 3 節で示した操作の合法性はそのまま成り立ちます。
出力量の制限を満たすこと
の箱の数を とします。 より であり、異なる正の高さの数は 以下です。 よって、ブロック数は です。
各ブロックの列の長さを とすると、高さを一段階下げるたびに新しい箱が少なくとも一つ加わるため、
です。これらは のうちの相異なる整数なので、
したがって、列の長さの総和も制限内です。 反復回数の上限については、次節で確認します。
6. アルゴリズムと計算量
実装する処理は次のとおりです。
- 石の総数を比較する。異なれば
-1。 - を累積和で求める。 が で割り切れなければ
-1。 - 隣接差から高さを復元し、最小値を引いて を求める。
- の箱に対して、 を満たす箱をキューで取り除く。箱が残ったまま止まれば
-1。 - 得られた順番 と、降順に並べた相異なる正の高さから、各ブロックを出力する。
回数の復元と順番の構築は 、高さのソートは です。 各ブロックの箱の列を作る処理に かかるので、全体の時間計算量は です。 付属の実装では全ブロックを保持するため、空間計算量も です。 順次出力する実装なら、作業用の空間は にできます。
整数の範囲
石の総数を とすると、 です。 任意の について、
です。右辺は、どちらも 以上 以下の二つの和の差なので、絶対値は 以下です。 よって、 の最大値と最小値の差も 以下です。
は の平均なので、 の絶対値は 以下です。 最大の高さの箱と最小の高さの箱は、隣り合う箱を高々 回たどれば結べるため、その高さの差は 以下です。 全体から最小値を引いても高さの差は変わらないので、
と抑えられます。各ブロックの反復回数は隣り合う の差なので、 となり、出力の制限を満たします。 累積和や高さの計算にも、符号付き 64 bit 整数を使えば十分です。
ユーザー解説
ユーザー解説を書くユーザー解説はまだありません。