CF1909I Short Permutation Problem 题解

这是一道 *1900 的黑。

考虑枚举 \(m\),将 \(<\frac m 2\)\(\ge \frac m 2\) 的数分开讨论。考虑相邻两个数 \(a,b\ (a>b)\) 分别在 \(\frac m 2\) 的两侧,则有 \(b\ge m-a\)

考虑将所有数按某种方法从小到大排序,以 \(\min(x,m-x)\) 为第一关键字,\(-x\) 为第二关键字,则排列中的相邻两个数满足条件必须有在上述序列中位置靠前的那个数 \(\ge \frac m 2\)

考虑对于每一个 \(k\) 求出钦定 \(k\) 对相邻的数满足条件的排列个数。这等价于将排列划分为 \(n-k\) 个段,每段中的任意相邻两个数均满足条件的排列个数。

接下来考虑根据上面发现的那个性质求这个东西。初始化有 \(c=n-k\) 个位置可以插入,然后依次枚举上述有序序列中的每个数插入,每次插入时方案数要乘上 \(c\),如果当前数 \(<\frac m 2\)\(c\) 减小一,否则 \(c\) 增加一。

发现这个序列的形态一定是在开头有若干个 \(\ge m\) 的数,接着 \(\ge \frac m 2\)\(< \frac m 2\) 的数交替出现。于是可以预处理出阶乘和所有可能用到的幂,每次 \(\mathcal O(1)\) 求出方案数。然后发现可能出现空段,二项式反演一下即可。

求出钦定 \(k\) 个的方案数以后就可以直接再二项式反演一遍,求出每个 \(k\) 的答案。然后就做完了,二项式反演可以 NTT 优化,记得系数的多项式要放在外面做变换,否则常数太大,时间复杂度 \(\mathcal O(n^2\log n)\)

code

posted @ 2024-05-24 22:41  zifanwang  阅读(6)  评论(0编辑  收藏  举报