我们考虑从 Ferrers diagram 的原点引出一条 y = x y=x y=x 的直线,它离开这个图的位置就框处了一个 h × h h \times h h×h 的正方形,这个正方形被称为一个整数拆分的 Durfee square。那么如果我们确认了正方形的边长是 h h h,它两侧放置的就都是 ≤ h \le h ≤h 的整数划分。因此我们得到了整数划分的这样一个表达式:
∏ k ≥ 1 1 1 − x k = ∑ h ≥ 0 x h 2 ( ∏ k = 1 h 1 1 − x k ) 2 \prod_{k\ge1} \frac1{1-x^k} = \sum_{h\ge0} x^{h^2} \left(\prod_{k=1}^h \frac1{1-x^k}\right)^2 k≥1∏1−xk1=h≥0∑xh2(k=1∏h1−xk1)2
在计算前 n n n 项时,由于 h 2 ≤ n h^2\le n h2≤n,我们只需要完成前 n \sqrt n n 项的 h h h 即可。
因此我们只需要这几行核心代码即可完成计算,复杂度为 Θ ( n n ) \Theta(n\sqrt n) Θ(nn):
int b = sqrt(n);
ans[0] = tmp[0] = 1;
for (int i = 1; i <= b; ++i) {
for (int rep = 0; rep < 2; ++rep)
for (int j = i; j <= n - i * i; ++j)
add(tmp[j], tmp[j - i]);
for (int j = i * i; j <= n; ++j)
add(ans[j], tmp[j - i * i]);
}