BG
没啥好说的,现在才搞的确有点晚了。。
问题
又叫做拆分数
给定正整数n,求将n拆分成若干正整数的和的方案数,其中又分为可相同和不可相同两个问题
整数划分1
考虑每个数字不能相等要怎么做
一个经典的dp是设f[i,j]表示拆分成i个数字,它们的和为j的方案数。
我们钦定所有数字降序排列,那么每次可以新增一个数字,或者全部加一,因此
f
[
i
,
j
]
=
f
[
i
−
1
,
j
−
i
]
+
f
[
i
,
j
−
i
]
f[i,j]=f[i-1,j-i]+f[i,j-i]
f[i,j]=f[i−1,j−i]+f[i,j−i]
可以发现i是 n \sqrt n n级别的,这样做就是 O ( n n ) O(n\sqrt n) O(nn)的,并且多组询问直接 O ( n ) O(n) O(n)求和就没了
整数划分2
同样考虑dp,这个问题可以看成有n个体积为1~n的物品装满容量为n的完全背包的方案数
不妨设
m
=
n
m=\sqrt n
m=n,对于体积
≤
m
\le m
≤m的物品只有n种,因此做完全背包是
O
(
n
n
)
O(n\sqrt n)
O(nn)的
对于体积
≥
m
\ge m
≥m的物品总共只会选
n
\sqrt n
n个,设f[i,j]表示i个数字和为j的方案数,转移
f
[
i
,
j
]
=
f
[
i
−
1
,
j
−
m
]
+
f
[
i
−
1
,
j
−
i
]
f[i,j]=f[i-1,j-m]+f[i-1,j-i]
f[i,j]=f[i−1,j−m]+f[i−1,j−i]
当然最后还要合并两个背包,这样做总的复杂度是
O
(
n
n
)
O(n\sqrt n)
O(nn)的,并且不支持多组询问。。
考虑这样一个函数
P
(
x
)
=
∏
i
≥
0
(
1
1
−
x
i
)
P(x)=\prod\limits_{i\ge0}\left(\dfrac{1}{1-x^i}\right)
P(x)=i≥0∏(1−xi1)
和这样一个函数
Q
(
x
)
=
∏
i
≥
0
(
1
−
x
i
)
Q(x)=\prod\limits_{i\ge0}\left(1-x^i\right)
Q(x)=i≥0∏(1−xi)
显然
P
(
x
)
Q
(
x
)
=
1
P(x)Q(x)=1
P(x)Q(x)=1,并且
P
(
x
)
P(x)
P(x)是整数拆分的生成函数
五边形数定理:
Q
(
n
)
=
∑
i
=
−
∞
∞
(
−
1
)
i
x
i
(
3
i
−
1
)
2
=
1
+
∑
i
=
1
∞
(
−
1
)
i
x
i
(
3
i
±
1
)
2
Q(n)=\sum_{i=-\infty}^{\infty}(-1)^ix^{\frac{i(3i-1)}{2}}=1+\sum_{i=1}^{\infty}(-1)^ix^{\frac{i(3i\pm1)}{2}}
Q(n)=i=−∞∑∞(−1)ix2i(3i−1)=1+i=1∑∞(−1)ix2i(3i±1)
具体的证明可以看这里
由于五边形数是n2级别的,因此递推这个东西是 O ( n n ) O(n\sqrt n) O(nn)的,并且资瓷多组询问
考虑在模意义下做这个问题,我们可以用多项式ln+多项式exp做到
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
具体看这里