南外集训 2024.2.15 T3
题目描述还能有错的?
\(T\) 组询问,每次给定 \(n, k\),问:如果一个 \(2n\) 个数的排列所有偶数位置构成的子序列是单调递增的,那么说这个排列是好的。将一个好的排列按照顺序拆分成若干组,每一组个数都是偶数,形成的结构叫做一个城市。一个城市的价值是每个组内部的逆序对个数的乘积。求从所有城市中随机选取一个,它的代价的数学期望。
你实际上需要输出答案乘以 \(\binom{n-1}{k-1}\),这是因为
std
和原题题意中有一个写错了。\(1\le T\le 10^4, 1\le k\le n\le 500\)
注意到城市的代价可以这样描述:从每个组内选择一个逆序对,这样选择的方案数。所以我们可以转而计算对于所有选择 \(k\) 对元素的方法,允许这样选择的城市个数之和。选择的逆序对有两种情况:两个奇数位置或一个奇数一个偶数。我们将所有偶数位置,以及后一种情况涉及到的奇数位置叫做关键位置。显然我们只需选择一些标号分配给关键位置,乘上关键位置的合法排列方案数,再随意排列非关键位置即可。对于前一种逆序对,显然它会在随意排列非关键位置的过程中贡献 \(\frac{1}{2}\) 的系数,直接在 DP 时乘上即可。现在我们关心这样一个问题的做法:
给定一条长度为 \(n\) 的单向链,每个元素旁边可能啥也不挂,可能挂一个指向它的元素,可能挂一个被它指向的元素,这样形成了一个非常特殊的有向无环图,求它的拓扑序个数。
我们可以在访问到内向节点的时候,直接在前面任意选择一个空位插入这个节点;在访问到外向节点时,把这个节点拿在手里;每次访问完一个节点,都可以任意选择手里的一些节点,按照任意顺序把它们放在当前节点后面。从而我们只需要在 DP 状态里记录目前总共放下了多少个节点,以及手里拿着多少外向节点没放下。
这样立刻得到原题的一种 DP 做法:\(f_{i,j,t,l,S}\) 表示前 \(2i\) 个元素,分了 \(j\) 组,当前总共放下了 \(t\) 个关键节点,还有 \(l\) 个外向的关键节点没有放下,且当前组内选择关键节点位置的状态是 \(S\)(\(S = \Theta(1)\)),此时的方案数。这个 DP 可以预处理,答案就是:
其中 \(S = \mathtt{ok}\) 表示在当前组内已经选择了全部的两个关键位置。转移是平凡的。这个做法时间复杂度是 \(\Theta(n^4)\)。
注意到我们只是为了处理外向节点加入了一维信息。现在使用容斥处理:加入一个外向节点时,按照这个节点不算入关键节点进行一次转移,然后按照这个节点是内向关键节点进行一次系数为 \(-1\) 的转移。复杂度立刻变成 \(\Theta(n^3)\)。大力卡常可以通过。