ARC068F
ARC068F
给定 \(n,k\),按照如下规定:
- 将 \(1\sim n\) 依次加入双端队列,每次可以从头部/尾部。
- 然后将其依次弹出(可从头部,从尾部)
问有多少个排列满足:
- \(1\) 恰好在第 \(k\) 个位置。
- 可以通过上述规则生成。
\(n,k\le 2000\)
\(\rm Sol:\)
加入 \(n\) 个元素得到的队列是合法的,当且仅当以 \(1\) 为中心,两端递减。
考虑一个弹出序列,在弹出 \(1\) 之前,其必然只能从两端依次弹出,所以等价于 \(1\sim k-1\) 这些位置中存在至多两个双递减序列(不一定连续)
然而这个条件不充分,考虑剩余的位置,显然还要有上述两个队列结尾的最大值比后续序列中的最大值要大。
对于后续序列,我们每次都可以从头部/尾部弹出,弹至长度为 \(1\) 时两者等价,所以这里的方案数为 \(2^{n-k-1}\)
于是现在我们的判定条件为:
- \([1,k)\) 中能分成两个递减序列。
- 两者中结尾的最大值比剩余元素的最大值大。
这样的一个 \([1,k)\) 填数的方案对答案的贡献为 \(2^{n-k-1}\)
注意到两个序列是递减的,第二个条件其实间接说明从值域上看,\([x,n]\) 这样的一段区间一定是被填满的。
然而直接 dp 容易计重,我们考虑一个绝妙的手段(个人认为确实很妙orz出题人)来约束序列使得其不会被计重,假设序列 S 是合法的,同时我们可以分割成两个双递减序列 A 和 B,那么我们可以证明,存在一种合法的划分方案使得任意一个位置上均有 A 的结尾小于 B 的结尾。
证明是显然的。
事实上我们总存在一个方案来调整答案,即交换 A 和 B 中的一段区间的属于关系来满足限制。
于是现在可以 dp 了,设 \(f_{i,j}\) 表示考虑到位置 \(i\),当前 A 序列的最小值为 \(j\),每次填入如果更小的值就一定划给了 A,否则划给了 B,同时 B 在值域上是连续的(存在的间隔会划分给结尾段导致 B 的结尾小于后续的最大值),所以选的数固定,同时根据 \(i,j\) 我们也可以容易的推断出当前能否继续填入 B ( \(j\) 小于等于 \(n-i+1\))。
转移通过维护一个后缀和优化,复杂度 \(\mathcal O(n^2)\)
事实上可以翻转下标 \(i\to n-i+1\),这样转移变成了一个前缀求和的形式,同时对于第 \(i\) 个位置,条件变为 \(j\ge i\) 。
由于最后求的答案有一个前缀和,我们考虑给这 \(k-1\) 个位置补充一个位置,然后计算 \(f_{k,n-1}\) 的值,显然他就是答案(等价于补了一个位置来计算前缀和)
然后考虑将答案描述成一个网格图上走路的过程,那么问题变成从 \((0,0)\) 走到 \((K,n-1)\),每次可以给 \(x+1\),\(y\) 增加任意,且对于任意的 \(x=i\) 均有对应 \(y\ge i\) 的方案数(假设 \(K\ne n\))。
直接计算仍然非常麻烦,考虑每次走的步数,设 \(a_i\) 表示在第 \(x=i-1\) 时走到 \(i\) 时走的步数,那么条件等价于 \(\sum_{i\le j} a_i\ge j\)
然后考虑容斥,设 \(f_i\) 表示到达位置 \(i\) 时权值和为 \(i\) 且沿途没有非法的方案数,显然得知了 \(f_{0\sim k-1}\) 就可以推出答案了,然后考虑总方案数,每个位置的取值可以是 \(0\sim \infty\to \frac{1}{1-x}\),所以所求即:
然后我们减去非法的,枚举第一次非法的位置 \(j\),那么显然此时 \(j-1\) 合法等价于前缀和为 \(j-1\),同时 \(j\) 处取值为 \(0\),同时接下来即有 \(i-j\) 个位置放置 \(i-j+1\) 的权值的方案数即 \(\frac{1}{(1-x)^{i-j}}[x^{i-j+1}]\to \binom{2(i-j)}{(i-j)}\)
所以有:
稍微改写变成:
显然可以写成生成函数:\(F(x)=G(x)-xF(x)\times H(x)+xF(x)+1\)
然后求逆即可,不过模数不太好就要 MTT 了。。。复杂度 \(\mathcal O(n\log n)\)
emm 上面是博主脑子 瓦特 写的,实际上可以做到线性,具体大概是简单的 trick(折线法)