AOJ 2638 Hyperrectangle を FPS で考える
概要
FPS で考えます。
(包除原理による解説は例えば次を参照ください)
なぜ FPS か?
各 の制約と、総和の制約を見て、FPS を直感しました。
実際、 を 以上 以下の 整数 とすると、 を満たす列 の個数は次のように書けます。
\begin{align*}
[x ^ s] \frac{1}{1 - x} \prod _ {i = 1} ^ d \frac{1 - x^{l_i + 1}}{1 - x}
\end{align*}
を満たす列 を考えた後で、 累積和を取れば良いです。
この式で を満たす格子点の個数は求められました。
体積を近似する
問題は が 実数 であることです。FPS は離散値を扱いやすいので、 点の間隔を小さくしていって、体積を近似することを考えます。
個に分割するとして、 とおきます。各軸の選択は次のようになります。
\begin{align*}
&\phantom{=} \sum_{e=0}^{l_i - 1} \left(x^e + x^{e + \varepsilon} + x^{e + 2\varepsilon} + \dots + x^{e + 1 - \varepsilon} \right) \\
&= \left(1 + x^{\varepsilon} + x^{2\varepsilon} + \dots + x^{1 - \varepsilon} \right) \sum_{e=0}^{l_i - 1} x^e \\
&= \frac{1 - x}{1 - x^\varepsilon} \cdot \frac{1 - x^{l_i}}{1 - x} = \frac{1 - x^{l_i}}{1 - x^\varepsilon}
\end{align*}
指数部分に非整数があるので FPS から外れていますが、 倍に引き伸ばせば正当になると思っています。
個に分割したときの近似体積 は次のように書けます。 累積和をとるときに も考慮する必要があることに注意します。
\begin{align*}
V_k &= \varepsilon^d \times [x^s] \frac{1}{1 - x^{\varepsilon}} \prod_{i=1}^{d} \frac{1 - x^{l_i}}{1 - x^\varepsilon} \\
&= \varepsilon^d \times [x^s] \left(\frac{1}{1 - x^{\varepsilon}}\right)^{d+1} \prod_{i=1}^{d} \left(1 - x^{l_i}\right)
\end{align*}
とします。負の二項定理から
\begin{align*}
V_k = \varepsilon^d \sum_{i + j = s} \binom{i / \varepsilon + d}{d} \times f_j = \frac{1}{d!} \sum_{i+j = s} \frac{(i / \varepsilon + d)!}{(i / \varepsilon)!} \times \varepsilon^d \times f_j
\end{align*}
ここで
\begin{align*}
\frac{(i/\varepsilon + d)!}{(i/\varepsilon)!} \times \varepsilon^d &= \left(\frac{i}{\varepsilon} + d\right)\left(\frac{i}{\varepsilon} + d - 1\right) \dotsm \left(\frac{i}{\varepsilon} + 1\right) \times \varepsilon^d \\
&= (i + d\varepsilon) (i + (d-1) \varepsilon) \dotsm (i + \varepsilon) \longrightarrow i^d \ (\varepsilon \to 0)
\end{align*}
よって求める値は次のようになります。
\begin{align*}
d! V = \sum_{i+j=s} i^d \times f_j
\end{align*}
計算量
とします。 は 個の疎な多項式の積です。 愚直な計算は です (今回はこれが間に合う制約で、実装も軽い)。exp-log テクで になります。