五边形数$p_i$定义为:$\frac{i(3i - 1)}{2}$。

一个定理:$\prod_{i=1}^{\infty} (1 - x^i) = \sum_{i=-\infty}^{\infty} (-1)^i x^{p_i}$。

证明自行看维基。

接下来看一道题:

题目链接

题意:对于$1 \leqslant i \leqslant n$,求$i$的整数拆分方案数。$1 \leqslant n \leqslant 10^5$。

显然答案的生成函数为$\prod_{i=1}^{\infty} \frac{1}{1 - x^i}$。然后我们就可以先ln再加起来再exp回去了。

那么我们就是要对$\prod_{i=1}^{\infty} (1 - x^i)$求逆。根据上面的定理,这个多项式在次数$\leqslant n$的时候非$0$的项数是$O(\sqrt{n})$级别的,那么我们就可以暴力求逆了,复杂度为$O(n\sqrt{n})$。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000, mod = 998244353;
int n, f[maxn + 10];

inline int dec(int x, int y) {
x -= y; return x < 0 ? x + mod : x;
}
inline int mul(int x, int y) {
return 1ll * x * y % mod;
}

int main() {
scanf("%d", &n); f[0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = -300; j <= 300; ++j) {
int v = j * (3 * j - 1) / 2;
if (v <= i && v) f[i] = dec(f[i], mul(f[i - v], j & 1 ? mod - 1 : 1));
}
printf("%d\n", f[i]);
}
}