区間 の長さを とします。これを 個の非空な連続部分文字列に分割するとき、分割された各文字列の長さを平均化すると、基本となる長さは となります。余りである 個の文字列については、長さを にすることができます。スコア(最小値)を最大化するためには、すべての文字列の長さを 以上にするのが最適です。したがって、答えとなる文字列の長さは基本的に であると決め打つことができます。
ここで、文字列 は 123456789 の繰り返しであるため、長さ の文字列は「周期 9 のうち、どの数字(開始位置)から始まるか」によって 9 種類しか存在しません。これにより、答えとなる「スコアの最大値」の候補は、この 9 種類の文字列のいずれかに絞られます。したがって、これら 9 種類の候補を辞書順(数値順)に大きい方から試し、「その文字列を最小値とする 分割が可能か?」という判定問題を解くことに帰着できます。
ある開始位置(数字)から始まる長さ の文字列を閾値 としたとき、 を 分割してすべてのピースを 以上にできるかを判定します。左端から貪欲に切り出すことを考えます。ある開始位置 から長さ を切り出したとき、その文字列が 以上であればコスト 0(消費文字数 )で条件を満たします。もし 未満になってしまう場合は、1 文字余分に切り出して長さ にすれば、桁数が増えるため確実に より大きくなります(コスト 1、消費文字数 )。この操作を 回繰り返し、追加で消費したコストの合計が、全体で許容される余り文字数 以下に収まるならば分割可能です。
このシミュレーションをクエリごとに 回(最大 回)行うと TLE(実行時間超過)となるため、ダブリングを用います。状態として dp[i][j][k][dc] を、「閾値の開始位置が 、基本の長さ が 、現在の開始位置 から出発して、 個の区間を切り出したときに必要な追加コストの合計」と定義します。同時に、遷移先の開始位置は のように計算できます。これを前計算しておくことで、各クエリの判定を で行うことができます。
ダブリングによって条件を満たす最大の閾値 (開始位置と長さ )が特定できたら、その文字列が表す数値を で求めます。 が非常に大きいため、愚直なループでは計算できません。 文字列 の 9 桁分のブロックの値を とします。長さ の文字列は、このブロック が 回繰り返され、最後に余りの 桁がくっついた形になります。繰り返されるブロック部分は、 という等比数列の和として表せます。この和は公式により と計算できます。除算については、 の法 における逆元を前計算しておくことで、各クエリ (または )で高速に求めることができます。最後に、この結果を 倍して左にシフトし、末尾の端数部分の数値を足し合わせれば、最終的な答えが得られます。
前計算(ダブリングのテーブル構築)には の時間しかかかりません。各クエリにおいては、9 つの候補に対してダブリングを用いて判定を行うため、1 クエリあたりの計算量は となります。値の復元にかかる計算量も繰り返し二乗法を用いれば です。全体として時間計算量は となり、制限時間内に十分に間に合います。また、定数倍の重い入出力処理(std::endl によるフラッシュなど)を避け、逆元を事前計算しておくことが重要です。