直接上例题。
容易发现对于一个体积为 \(a_i\),数量为 \(b_i\) 的物品,我们可以把它的选法写成生成函数的形式:
\[\sum\limits_{k=0}^{b_i} x^{k \cdot a_i} = \frac{1 - x^{a_i (b_i + 1)}}{1 - x^{a_i}}
\]
若 \(b_i = 0\) 则生成函数为:
\[\sum\limits_{k=0}^{\infty} x^{k \cdot a_i} = \frac{1}{1 - x^{a_i}}
\]
所以我们可以将答案的生成函数写为这些物品生成函数乘积的形式。设 \(1 - x^i\) 的次数为 \(s_i\)(注意到 \(\frac{1}{a} = a^{-1}\)),那么答案的生成函数即为:
\[F(x) = \prod\limits_{i=1}^{\infty} (1 - x^i)^{s_i}
\]
我们发现这个东西不太好直接求解。我们注意到这是一串乘积的形式,所以我们可以通过取 \(\ln\) 来变成加法的形式,即:
\[\ln F(x) = \sum\limits_{i=1}^{\infty} s_i \ln(1 - x^i)
\]
对于形如 \(\ln (1 - a)\),我们可以注意到:
\[\frac{d \ln (1-a)}{d a} = - \frac{1}{1-a} = - \sum\limits_{n=0}^{\infty} a^n
\]
\[ln(1 - a) = \int (- \sum\limits_{n=0}^{\infty} a^n) d a= - \int (\sum\limits_{n=0}^{\infty} a^n) d a = - \sum\limits_{n=1}^{\infty} \frac{1}{n} a^n
\]
所以:
\[\begin{aligned}
\ln F(x) &= \sum\limits_{i=1}^{\infty} s_i \sum\limits_{j=1}^{\infty} \frac{1}{j} x^{ij}
\\
&= \sum\limits_{i=1}^{\infty} \sum\limits_{j=1}^{\infty} \frac{s_i}{j} x^{ij}
\end{aligned}
\]
我们只需要求前 \(n\) 项的系数,所以直接模上 \(x^n\)。然后可以发现上面的 \(\ln F(x)\) 是可以调和级数枚举倍数计算的,求出 \(\ln\) 后再 \(\exp\) 回去即可。时间复杂度 \(O(n \log n)\)。
和上面那道题很像,区别是我们现在知道了 \(F(x)\),要求 \(s\) 集合。那我们显然可以先对 \(F(x)\) 取 \(\ln\),然后再根据系数逆推回 \(s\)。时间复杂度还是 \(O(n \log n)\)。不过很恶心的是这道题要写 MTT。
直接写出答案的生成函数:
\[\begin{aligned}
F(x) &= \sum\limits_{i=0}^{\infty} \sum\limits_{j=1}^{n} a_j^i x^i
\\
&= \sum\limits_{i=1}^{n} \sum\limits_{j=0}^{\infty} (a_i x)^j
\\
&= \sum\limits_{i=1}^{n} \frac{1}{1 - a_i x}
\end{aligned}
\]
我们看到了 \(\frac{1}{a}\) 的形式,发现它很像 \(\ln\) 的导数。然而:
\[\ln (1 - a_i x) = - \frac{a_i}{1 - a_i x}
\]
这里有一个系数 \(a_i\),然而我们的原式中没有 \(a_i\),需要配一个 \(\frac{1}{a_i}\),非常不好。我们尝试把 \(1\) 的系数变为 \(a_i\)。
\[\begin{aligned}
F(x) &= \sum\limits_{i=1}^{n} (\frac{a_i x}{1 - a_i x} + 1)
\\
&= n + x \sum\limits_{i=1}^{n} \frac{a_i}{1 - a_i x}
\end{aligned}
\]
我们设:
\[G(x) = \sum\limits_{i=1}^{n} \frac{a_i}{1 - a_i x}
\]
那么:
\[\begin{aligned}
\int G(x) dx &= \int (\sum\limits_{i=1}^{n} \frac{a_i}{1 - a_i x}) dx
\\
&= \sum\limits_{i=1}^{n} \int \frac{a_i}{1 - a_i x} dx
\\
&= - \sum\limits_{i=1}^{n} \ln(1 - a_i x)
\\
&= - \ln \prod\limits_{i=1}^{n} (1 - a_i x)
\end{aligned}
\]
对于:
\[\prod\limits_{i=1}^{n} (1 - a_i x)
\]
我们使用分治 NTT 求解,然后取 \(\ln\) 之后再求导就得到了 \(G(x)\),然后再搞后面的。时间复杂度 \(O(n \log^2 n)\)。
我们知道:
\[\begin{aligned}
f(x) &= \sum\limits_{i=1}^{n} y_i \prod\limits_{j \neq i} \frac{x - x_j}{x_i - x_j}
\\
&= \sum\limits_{i=1}^{n} \frac{y_i}{\prod\limits_{j \neq i} (x_i - x_j)} \prod\limits_{j \neq i} (x - x_j)
\end{aligned}
\]
现在我们想对每个 \(i\) 求:
\[g(x_i) = \prod\limits_{j \neq i} (x_i - x_j)
\]
我们发现:
\[g(x) = \sum\limits_{i=1}^{n} \prod\limits_{j \neq i} (x - x_j)
\]
因为你把 \(x_i\) 带进去的时候,只有在 \(i\) 处求和时后面的乘积才非零。
若设
\[h(x) = \prod\limits_{i=1}^{n} (x - x_i)
\]
那么根据求导的乘法法则:
\[g(x) = h'(x)
\]
或者换一种方式来理解:
\[g(x_i) = \lim_{x \to x_i} \frac{h(x)}{x - x_i}
\]
我们发现:
\[\lim_{x \to x_i} h(x) = 0
\]
\[\lim_{x \to x_i} (x - x_i) = 0
\]
所以我们考虑使用洛必达法则,上下求导得到:
\[g(x_i) = \lim_{x \to x_i} \frac{h'(x)}{1} = h'(x_i)
\]
所以我们用分治 NTT 求出 \(h(x)\),再求出 \(h'(x)\) 后使用多项式多点求值即可求得所有 \(g(x_i)\)。那么:
\[f(x) = \sum\limits_{i=1}^{n} \frac{y_i}{g(x_i)} \prod\limits_{j \neq i} (x - x_j)
\]
而这个问题可以使用分治 NTT 求解。这样我们就在 \(O(n \log^2 n)\) 的复杂度内得到了 \(f(x)\)。