*2300 的 组合计数。
两个条件:
-
1≤a1≤b1<a2≤b2 ... <ak≤bk≤n。
-
bi−ai 互不相同。
肯定要预处理所有
(n,k) 组合的答案,因为
t 很大,但
n,k 较小。
先尝试求出有解的充要条件。根据条件 1 可知,相邻一对至少会增加
1,有
k−1 次增加,因此有
bk−a1=(i=1∑kbi−ai)+k−1≤n−1,解得
(i=1∑kbi−ai)≤n−k。
根据条件 2,有下界
i=1∑kbi−ai≥i=1∑ki−1=2k×(k−1)。
由两个不等式有
2k×(k−1)≤n−k,因此
k2+k≤2×n。所以
k 很大是没有用的,因此只考虑
k≤50 即可,否则无解。
再来考虑 dp,对于一组询问
(n,k) 怎么算答案。对于条件 2 的
k 个数对,差值可以选择
0∼n,我们要固定选择
k 个数。
然后你在上述有解分析的时候大概想到了如果
bk−a1≤n−1,那你相当于还会剩下
n−(bk−a1)−1 次多余的“操作”可以加到
ai 里去。就是说对于
a1∼ak,你
最多还可以把
n−(bk−a1)−1 分配给他们。然后
bi 会对应的增加,是随着
ai 变化的,因此不需要管
bi。
但是这个
bk−a1 对于不同的在
n 个差值里选择
k 个的方案的情况下也是不同的。因此我们考虑枚举与这个相关的东西。
我们枚举选出的
k 个数的和为
j,其方案数记为
fj,k,那么可以算出你
最多可以分配的量为
(n−1)−j−(k−1)=n−j−k。具体细节后面再讲。
然后你选出的
k 个差值是可以任意调换的,因此要乘上
k!。然后枚举
p∈[0,n−j−k] 表示你要分配
p 个数给
k 个
ai。这个问题是经典的插板法,方案数为
(k−1p+k−1),这里不再赘述。因此这部分方案数为
p=0∑n−j−k(k−1p+k−1)。这个东西不要暴力求,可以预处理。
然后求
f 数组的话相当于是做一个背包,我们枚举
i 表示当前的
n,然后每次都
O(nk) 做一次 01 背包。对于
n=i 时统计答案,枚举
k,则
ansn=i,k=j∑n−1fj,k×k!×p=0∑n−j−k(k−1p+k−1) 。
预处理后复杂度是
O(n2k) 的,因为
k≤50 才有解因此是对的。