[航海协会]序列计数问题
Posted StaroForgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[航海协会]序列计数问题相关的知识,希望对你有一定的参考价值。
序列计数问题
题目概述
题解
首先看到这题目,应该比较容易想到生成函数。
第
i
i
i个数的生成函数显然是
F
i
=
∑
j
=
0
b
i
−
c
x
j
=
1
−
x
b
i
−
c
+
1
1
−
x
F_i=\\sum_j=0^b^i-cx^j=\\frac1-x^b^i-c+11-x
Fi=∑j=0bi−cxj=1−x1−xbi−c+1
答案要求
∑
x
i
<
n
\\sum x_i<n
∑xi<n,相当于就是全部乘起来,做个前缀和取第
n
−
1
n-1
n−1项,
其中,我们定义
f
(
S
)
=
∑
x
∈
S
b
x
f(S)=\\sum_x\\in Sb^x
f(S)=∑x∈Sbx表示
A
n
s
=
[
x
n
−
1
]
∏
i
=
1
m
1
−
x
b
i
−
c
+
1
(
1
−
x
)
m
+
1
=
[
x
n
−
1
]
∑
S
⊂
U
(
−
1
)
∣
S
∣
x
f
(
S
)
−
(
c
−
1
)
∣
S
∣
(
1
−
x
)
m
+
1
A
n
s
=
∑
S
⊂
U
(
−
1
)
∣
S
∣
(
n
+
m
−
1
+
(
c
−
1
)
∣
S
∣
−
f
(
S
)
m
)
Ans=[x^n-1]\\frac\\prod_i=1^m 1-x^b^i-c+1(1-x)^m+1=[x^n-1]\\frac\\sum_S\\subset U(-1)^|S|x^f(S)-(c-1)|S|(1-x)^m+1\\\\ Ans=\\sum_S\\subset U(-1)^|S|\\binomn+m-1+(c-1)|S|-f(S)m
Ans=[xn−1](1−x)m+1∏i=1m1−xbi−c+1=[xn−1](1−x)m+1∑S⊂U(−1)∣S∣xf(S)−(c−1)∣S∣Ans=S⊂U∑(−1)∣S∣(mn+m−1+(c−1)∣S∣−f(S))直接枚举集合
S
S
S可以做到
O
(
2
m
m
)
O\\left(2^mm\\right)
O(2mm),但都做到这里了我们何必暴力枚举集合呢?
考虑再给它化一下,
A
n
s
=
1
m
!
∑
S
⊂
U
(
n
+
m
−
1
+
(
c
−
1
)
∣
S
∣
−
f
(
S
)
)
m
‾
Ans=\\frac1m!\\sum_S\\subset U(n+m-1+(c-1)|S|-f(S))^\\underline m
Ans=m!1S⊂U∑(n+m−1+(c−1)∣S∣−f(S))m显然可以数位
d
p
dp
dp,我们可以将后面的下降幂看成一个多项式,然后
d
p
dp
dp维护。
为了同时保证后面下降幂那东西不小于
m
m
m,我们枚举的
f
(
S
)
f(S)
f(S)显然得有一个上限,不能超过
n
+
m
−
1
+
(
c
−
1
)
∣
S
∣
n+m-1+(c-1)|S|
n+m−1+(c−1)∣S∣,这个上限与
∣
S
∣
|S|
∣S∣有关,所以我们可以考虑先枚举
∣
S
∣
|S|
∣S∣,再根据当前的上限数位
d
p
dp
dp。
定义
d
p
i
,
j
,
k
,
0
/
1
dp_i,j,k,0/1
dpi,j,k,0/1表示在前
i
i
i位中,选择了
j
j
j位,并且是否达到上限的集合
S
S
S的
f
(
S
)
k
f(S)^k
f(S)k次方之和。
转移显然就是每次枚举是否加入当前的
2
i
2^i
2i嘛,但由于需要转移每个次方的值,我们的复杂度会达到惊人的
O
(
m
5
)
O\\left(m^5\\right)
O(m5),考虑优化。
注意到
2
−
b
⩽
c
⩽
b
−
1
2-b\\leqslant c\\leqslant b-1
2−b⩽c⩽b−1,显然,当
b
>
2
b>2
b>2时,有
(
b
n
−
c
+
1
)
⩾
∑
i
=
1
n
−
1
(
b
i
−
c
+
1
)
(b^n-c+1)\\geqslant \\sum_i=1^n-1(b^i-c+1)
(bn−c+1)⩾∑i=1n−1(bi−c+1)。
也就是说,我们可以尝试求出当前能够选择的字典序最大
S
S
S,显然,比这字典序小的
S
S
S都是可以被选择的。
这样我们就可以只对一个
n
n
n进行数位
d
p
dp
dp了,优化到
O
(
m
4
)
O\\left(m^4\\right)
O(m4)。
对于
b
=
2
,
c
=
1
b=2,c=1
b=2,c=1时,上面的结论依旧成立。
对于
b
=
2
,
c
=
0
b=2,c=0
b=2,c=0时,一种简单的方法就是先将所有小于
n
n
n的
f
(
S
)
f(S)
f(S)全部计算,再减掉
f
(
S
)
+
∣
S
∣
⩾
n
f(S)+|S|\\geqslant n
f(S)+以上是关于[航海协会]序列计数问题的主要内容,如果未能解决你的问题,请参考以下文章