CF1821F - Timber

发布时间 2023-04-25 16:10:21作者: jucason_xu

\[逐渐变成自己最讨厌的样子 \]

首先考虑 \(dp\),设 \(dp_{i,j}\) 表示当前放了 \(i\) 个树,目前不得不覆盖到的最右点为 \(j\),每放一棵树,如果能往左就往左,否则往右倒。

\(\text{GF}\)

首先考虑 \(dp_{i,j}\) 的转移。

第一种,在 \([j+1,j+k]\) 放一个树,它只能往右倒,最终会对 \(j'\in [j+1+k,j+2k]\)\(dp_{i+1,j'}\) 进行一次贡献。

第二种,在 \([j+k+1,n]\) 放一个树,它可以往左倒,最终会对 \(j'\in [j+k+1,n]\)\(dp_{i+1,j'}\) 进行一次贡献。我们发现,即使贡献到 \(n\) 以外的位置也没有关系,所以这里可以直接把贡献区间改成 \([j+k+1,+\infty]\),别问,问就是生成函数的封闭形式好求。

然后我们发现,这个转移是一个卷积的形式,我们可以写出 \(F_i(x)=\sum_{n=0}^{\infty}dp_{i,n}x^n\),然后得到 \(F_{i+1}(x)=F_i(x)G(x)\),通过递推形式的转移式得到 \(G(x)=\sum_{n=k+1}^{2k}2x^n+\sum_{n=2k+1}^{\infty} x^n\)

我们发现,我们其实就是要求 \(F_m(x)\) 的前 \(n\) 项系数和,也就是计算 \(G^m(x)\)\(F_0(x)=1\)),只要能快速计算出 \(G^m(x)\) 的前 \(n\) 项就可以了。

这里我就直接莽了一个暴力的多项式模 \(x^n\) 意义下快速幂,运用 \(\text{NTT}\) 可以做到 \(O(n\log^2 n)\) 的复杂度。然而这个算法的常数实在太大了,首先 \(\text{NTT}\) 实际要做长度为 \(1048576\) 的数组(最小的大于 \(2n\)\(2\) 的幂),然后快速幂过程中每次乘法需要 \(3\)\(\text{NTT}\)。这个代码在极限数据运行了 6s,据说可以优化,但是递归式快速幂空间也炸掉了,难蚌。

(据说还有 \(O(n\log n)\) 的多项式快速幂科技,但是不会)

我们考虑 \(G(x)\) 的封闭形式,

\(\sum_{n=k+1}^{2k}x^n+\sum_{n=k+1}^{\infty}x^n\)

提出 \(x^{k+1}\) 出来,变成 \(x^{k+1}(\sum_{n=0}^{k-1}x^n+\sum_{n=0}^{\infty} x^n)\)

然后就直接封闭形式了,\(x^{k+1}\dfrac{2-x^k}{1-x}\)

\(G^m(x)=x^{k+1}\dfrac{2-x^k}{1-x}=x^{mk+m}\dfrac{(2-x^k)^m}{(1-x)^m}\)

求它的前 \(n\) 项系数和。不过我们可以直接乘上一个 \((1-x)^{-1}\) 做一次前缀和,转化为 \(x^{mk+m}\dfrac{(2-x^k)^m}{(1-x)^{m+1}}\) 的第 \(n\) 项系数,\(\dfrac{(2-x^k)^m}{(1-x)^{m+1}}\) 的第 \(n-mk-m\) 项系数。

考虑二项式定理展开上面的,变成 \(\sum_{i=0}^m\dfrac{\binom{m}{i}2^{m-i}(-x^k)^{i}}{(1-x)^{m+1}}\)

对于每一个子生成函数,我们都只研究它的第 \(n-mk-m\) 项系数。我们发现我们其实只要求 \(\dfrac{1}{(1-x)^{m+1}}\)\(s=n-mk-m-ik\) 项系数。没有这一项就直接是 \(0\)。然后这个东西的泰勒展开是好求的,直接套牛顿公式 \(\binom{-m-1}{n-mk-m-ik}\),变成 \(\dfrac{(-1)^s(-1)^s(m+s)!}{s!m!}\),发现就是 \(\binom{m+s}{m}\)

得到最终的公式

\(ans=\sum_{i=0}^m\binom{m}{i}2^{m-i}(-1)^{i}\binom{n-mk-ik}{m}\)

二项式反演

我们考虑这个 \(dp\) 式子,我们发现,每次从 \(i\) 转移到 \([i+k+1,i+2k]\) 的权值是 \(2\),转移到 \([2k+1,\infty]\) 的权值是 \(1\)。这个怎么理解呢?我们也可以理解成,一个右端点方案的权值是 \(2^x\),其中 \(x\)\(p_{i}-p_{i-1}\le 2k\) 的次数

我们就可以把问题等价的转化成划分问题,我们要把 \(\le n\) 的长度划分成 \(m\) 段,每段的长度不低于 \(k+1\),并且每个长度在 \([k+1,2k]\) 的段的贡献都是 \(2\)

然后我们可以设 \(f_i\) 表示恰好有 \(i\) 段的长度 \(>2k\) 的方案数。答案就是 \(\sum_{i=0}^m2^{m-i}f_i\)

然后设 \(g_i\) 表示钦定有 \(i\) 段长度 \(>2k\) 的方案数,\(g_i=\sum_{j=i}^m \binom{m}{j}f_j\),同时 \(g_i=\binom{m}{i}\binom{n-mk-ik}{m}\)

运用二项式反演,\(f_i=\sum_{j=i}^m(-1)^{j-i}\binom{j}{i}g_j\)

套进式子里,
\(ans=\sum_{i=0}^m2^{m-i}\sum_{j=i}^m(-1)^{j-i}\binom{j}{i}g_j\)
\(=\sum_{i=0}^m\sum_{j=i}^m2^{m-i}(-1)^{j-i}\binom{j}{i}g_j\)
\(=\sum_{j=0}^mg_j\sum_{i=0}^j2^{m-i}(-1)^{j-i}\binom{j}{i}\)

后面就变成了二项式定理,得到
\(ans=\sum_{j=0}^mg_j2^{m}\sum_{i=0}^j(\dfrac{1}{2})(-1)^{j-i}\binom{j}{i}\)
\(=\sum_{j=0}^mg_j2^{m}(-\dfrac{1}{2})^j=\sum_{j=0}^mg_j2^{m-j}\)

就可以直接计算了。

向量

我们考虑另一种转移,我们先把每个都有的 \(k+1\) 提出来,变成划分 \(n-mk-m\)
\(dp_{i,j}\rightarrow dp_{i,j+1}\)
\(2dp_{i,j}\rightarrow dp_{i+1j+k+1}\)
但是我们发现,这样可能就对 \([2k+1,n]\) 造成多余转移,所以减掉,变成
\(-dp_{i,j}\rightarrow dp_{i+1,j+2k+1}\)

所以我们相当于加上一系列向量,使得 \(i\) 坐标达到 \(m\),其中三种向量的贡献分别是 \(\{1,2,-1\}\)。最终的答案就是所有方案的向量贡献积的和。

我们考虑枚举第三种转移做的个数,假设做了 \(x\) 次,那么第二种转移就应该做 \(m-x\) 次,以达到 \(i\) 坐标的目的。然后其中 \(j\) 坐标一共贡献了 \((m-x)(k+1)+(2k+1)x\),我们先安排第三种转移和第二种转移的顺序,应当是 \(\binom{m}{x}\),而接下来我们还可以加入 \(n-(m-x)(k+1)-(2k+1)x\) 个第一种转移。枚举一共加入了多少个,就是 \(\binom{m+n-(m-x)(k+1)-(2k+1)x}{m}\)

所以就是 \(\sum_{x=0}^m2^{m-x}(-1)^x\binom{m+n-(m-x)(k+1)-(2k+1)x}{m}\binom{m}{x}\)

也就可以解决了。