AtCoder ABC 136 E - Max GCD
問題概要
長さの整数列が与えられる。次の操作を回以上回以下行うことができる。
- なる以上以下のつの整数を選び、にを足し、にを足す。この操作の後いずれかの要素が負になってもよい。
操作後のの全ての要素を割り切る正の整数として考えられる値の最大値を求めよ。
制約
解説/考察
ステップ1
答えを、各に対して変化させる値をとおくと、
です。よって
が成り立ちます。またこのとき、問題文より
なので、
と変形できます。よって、答えはの総和の約数であることが分かります。
ステップ2
次に、答えの候補をとしたときに、回以内の操作で整数列の要素をの倍数にすることができるのか判定する方法を考えます。
各について、
- を引く(「-方向」)
- を足す(「+方向」)
ことによっての倍数にすることができます。= (「-方向」の量) - (「+方向」の量)とするとき、となっている必要があります。
まず最初に、の全ての要素を「-方向」に設定してみると、
です。また、これはの倍数となることがの総和がの倍数であることからわかります。
それでは、ここから1つの要素を「+方向」に変えてみます。このとき、の変化量は
となります。よって、 個だけ「+方向」に設定しなおせばよいことがわかります。操作回数は「+方向」に設定しなおした後に残った「-方向」の量です。どの要素を設定しなおしてもの変化量はなので、から、のうち大きい方から個の和を引いた値が操作回数の最小値となります。これによって求まった値が以内ならば、の要素をの倍数にすることができます。この判定方法をステップ1で挙げた答えの候補のうち大きい方から適用していくことで答えが求まります。
思考の流れ
- とりあえず文字でおいて式化してみる。
これはあらゆる問題で言えることですが、未知数を一つの文字で置いて、式の最終的な状態、最初の状態、条件式を書き出してみると重要なことが見えてくることが多いです。この問題で言うと、最初の変化量をと置くことで、最後の状態の式と条件式から、関係性を見出すことができます。
- 答えはの総和の約数で、約数の個数はあまり大きくならない(参考)ので、列挙して一つずつチェックしていけば良い。判定方法を考える。
- をの倍数にしたいとき、だけ引く、又はを足せばよいことがわかり、全体でこれをうまく調整することで「引く量」=「足す量」にしたい。
- 「引く量」と「足す量」の差を考えれば良さそう。式変形(あるいは実験)をすると、差がの倍数かつ、要素を一つ変えるごとに常に変化量がであることから、答えにたどり着く。
感想
コンテスト中、ステップ1を思いついたときは、これがこの問題の本質だと思っていましたが、どちらかというとステップ2の判定フェーズの方が骨が折れます。しかしステップ1に気付かなければ何も始まらなく、非常に考察力が試される問題だと思いました。