Official

F - 998244353 → 1000000007 Editorial by Nyaan


コンテスト後により直感的な解法が発見されたので説明します。(コンテスト後の MMNMM さんのツイートを部分的に参考にしました。ありがとうございます。)
簡単に説明すると、うまく \(x\) を取ってきて \(1/N\)\(x/R^2\) で近似する解法です。

この問題は整数 \(t\) に対して \(\lfloor t/N \rfloor\) を求めれば解くことができます。\(\lfloor t/R \rfloor\) は所与の命令で計算できるので、\(R^2/N\) に近い \(x\) を取ってきて\(t/N\)\(t\times x / R^2\) で近似して求めることを考えます。(\(N=10^9+7,R=998244353\) です。念のため)

\(B = R^2, x = \left\lfloor \frac{B}{N} \right\rfloor = 996491781\) とおきます。

\(0 \leq t \leq (N-1)^2\) である \(t\) に対して、\(\lfloor t/N \rfloor\)\(\lfloor tx/B \rfloor\) で近似することを考えます。両者の差を評価します。

\[f(t) = \frac{t}{N} - \frac{tx}{B} = t\left(\frac{B - Nx}{NB}\right)\]

とします。\(Nx\)\(B\) の間には、 \(r = B \bmod{N} = 343639189\) を用いて

\[B = Nx + r\]

という関係式が成り立つので、

\[0 \leq f(t) \leq \frac{tr}{NB} \leq \frac{(N-1)^2 r}{R^2 N} \lt 0.345\]

となります。ただし、\(tx\) はオーバーフローするので、\(\left\lfloor \frac{tx}{B} \right\rfloor\) の代わりに \(\lfloor(\lfloor t/R\rfloor x)/R\rfloor\) を計算します。\(t \bmod{R} = u\) として

\[0 \leq \frac{tx}{B} - \frac{\left\lfloor \frac{t}{R}\right\rfloor x}{R}= \frac{ux}{B} \leq \frac{(R-1)x}{R^2} \lt 0.999\]

です。よって

\[0 \leq \frac{t}{N} - \frac{\left\lfloor \frac{t}{R}\right\rfloor x}{R} \lt 1.344\]

が成り立つので、

\[0 \leq \left\lfloor \frac{t}{N} \right\rfloor - \left\lfloor \frac{\left\lfloor \frac{t}{R}\right\rfloor x}{R} \right\rfloor \leq 2\]

が言えます。よって \(q(t) = \left\lfloor\frac{\left\lfloor \frac{t}{R}\right\rfloor x}{R} \right\rfloor\) は真の \(t / N\) の商よりも高々 \(2\) 小さいので、 \(AB - q(AB) N\)\(\lbrack 0, 3N)\) の範囲に収まります。あとは公式解説の /R, if 文の実装方法を組み合わせればこの問題を解くことができます。

実装例 (snuke さん, hos さんの提出を一部参考にしました。なお、この問題のジャッジは改行, 空白を読み飛ばしているので可読性のために改行を入れても AC 扱いとなります)

なお、上記のアルゴリズムは Barrett reduction と呼ばれる手法に近いです。(AtCoder Library でも使用されています)

posted:
last update: