「ZJOI2020」抽卡
「ZJOI2020」抽卡
Sub1: 从$n$张卡中选取钦定的$m$张的期望次数
令$f_m$表示期望次数,显然$m>0,f_m=\frac{(n-m)f_m+mf_{m-1} } {n}+1$
即$f_0=0,f_m=f_{m-1}+\frac{n} {m}$
即$\displaystyle f_m=\sum_{i=1}^m \frac{n} {i}$
Minmax容斥转化
回到原问题的$a_1,a_2,\ldots,a_m$,按照连续$k$个分段,设每段开始点$A_i$
我们要求这些$[A_i,A_i+k)$第一次有一个被满足的期望,这难以解决
用一个$\text{minmax}$容斥处理掉
$\displaystyle \min\{\exists A_i合法\}=(-1)^{T+1}\sum_{T\subset S} \max\{\forall i\in T,A_i合法\}$
这个$\text{max}$显然取决于$A_i$并的长度
令$dp_{i,j}$表示当前最大的选择点为$i$,选择的总长度为$j$,容易用前缀和优化到$O(n^2)$
优化求解
容易想到对于每个长度$\ge k$的连续段分别求解,然后分治$\text{NTT}$背包合并
此时我们要对于连续$n$个元素可以选择的子问题求解答案生成函数$F_n(x)$
推论:对于某一个长度$L \in[k+2,2k]$的且已经确定都选择的段,其容斥系数为0
考虑此时,收尾两个段必须选择,而中间的段(个数$>0$)随意选择
由等式$\sum {T\in S} (-1)^{|T|}=[S=\empty]$可知,其系数为0
观察一下我们能由这个推论得到什么
令$dp_{n}$表示顺次覆盖前$n$个元素的系数
$dp_{k}=-1,dp_{k+1}=-dp_{k}=1$
$\forall i\in[k+2,2k],dp_i=0$
$dp_{2k+1}=-dp_{k+1}=-1$
$dp_{2k+2}=-dp_{2k+1}=1$
想必睿智的你一定已经发现了,$dp$数组$k+1$一循环
实际上根据这个性质的暴力$dp$可以多10pts
由于$dp_{k+1}=1$,也可以表示为$dp_{i}=dp_{k+1}\cdot dp_{i-k-1}$
因此可以把连续段的前$k+1$个分裂开来,假装不连续
此时,我们可以简单描述为:
每次选择的是一个长度为$k+1$的段
可以覆盖前$k$个,系数为$-1$
也可以覆盖$k+1$个,系数为$1$
并且这$k+1$个段不能相交,可以相邻
根据这样的决策,计算系数可以分为两步
$n$个元素选出$i$个长度为$k+1$的段,剩下的元素可以分配到这$i+1$个间隔中
方案数为$\displaystyle \binom{n-i(k+1)+i+1-1} {i+1-1}=\binom{n-ik} {i}$
一开始令这些段都选择前$k$个,然后对于某一些可以额外选择最后一个,乘上$-x$
由此我们列出$\text{OGF}$表达式
$\displaystyle G_n(x)=\sum_{i=0}^{\frac{n} {k+1} } (-1)^i\binom{n-ik} {i}x^{ik}(1-x)^i$
$\displaystyle G_n(x)=\sum_{i=0}^{\frac{n} {k+1} } \binom{n-ik} {i}x^{ik}(x-1)^i$
注意边界情况是最后$k$个被选的情况不会算进去,因此实际上
$F_n(x)=G_n(x)-x^kG_n(n-k)$
考虑如何计算$G_n(x)$
我们对于所有的$i$分治,分治到区间$[l,r]$时,我们维护的是
$\displaystyle \sum_{i=l}^{r} \binom{n-ik} {i}x^{(i-l)k}(x-1)^{(i-l)}$
这样就能保证分治时,区间内多项式长度为$O((r-l+1)(k+1))$
合并时,给右区间补上$x^{(mid-l+1)k}(x-1)^{mid-l+1}$即可
因此计算$F_n(x)$和合并$F_n(x)$的复杂度均为$O(n\log ^2n)$
不$sort$有80pts.jpg
代码好看就完事了
1 |
|