Loading

模拟赛 2024.2.15 解题报告

USACO19DEC

A B 没什么意义

C. Tree Depth

题意:对一个排列 \(a_{1...n}\) 构建笛卡尔树,对 \(\forall i\in [1,n]\),求:对于所有逆序对个数为 \(k\) 的排列 \(a\),点 \(i\) 的深度(其到根节点的点数)之和,答案对 \(m\) 取模。

\(1\le n\le 300,\space 0\le k\le \frac {n(n-1)}2,\space 10^8\le m\le 10^9+9\)


逆序对个数为 \(k\) 的排列个数是容易求的,设 \(f[i,j]\) 表示前 \(i\) 个数逆序对个数为 \(j\) 的方案数,每次确定 \(a_{1...i-1}\) 中多少个数比 \(a_i\) 大,转移为 \(f[i,j]=\sum\limits_{k=0}^{i-1}f[i-1,j-k]\)

考虑拆贡献,计算对于 \(i\)\(j(j\not =i)\) 是他的祖先的方案数。

发现条件 \(a_i>a_j\),且 \(i,j\) 之间的所有数字都要 \(>a_j\)

那么 \(a_j\) 是这一段的最小值,考虑计算方案数,我们先在 \(a\) 中放一个 \(a_j\)

然后放 \(i\sim j\) 这一段的其他数字,这个方案数可以通过上面的 dp 求。

最后是 \(i\sim j\) 之外的数字。放一个数字在前面,转移枚举后面多少个数比他小;放一个数字在后面,转移枚举前面多少个数字比他大。我们发现不管是前面还是后面放,枚举的数的范围是一样的,转移式都是一样的。

而且还发现上面的转移式其实相当于分组背包,第 \(i\) 组为 \(\{1,2,...,i-1\}\),背包可以用 GF 来搞。设 \(F_i(x)=\sum\limits_j f[i,j]x^j\),设 \(G_i(x)=\sum\limits_{j=0}^{i-1} x^j\),有

\[F_i(x)=F_{i-1}(x)\cdot G_i(x) \]

\(i\sim j\) 这一段的长度 \(l=|i-j|+1\),钦定 \(j<i\)(即 \(j\) 和这一段的其他数字没有产生逆序对),那么不难发现我们要求的东西就是

\[[x^k]G_1(x)G_2(x)...G_{l-1}(x)G_{l+1}(x)G_{l+2}(x)...G_n(x) \]

也就是 \([x^k]\frac{F_n(x)}{G_l(x)}\)\(j>i\) 同理。预处理所有 \(l\) 的答案,由于数据范围很小,暴力递推就行。时间复杂度 \(O(nk)\).

posted @ 2024-02-15 18:50  Lgx_Q  阅读(11)  评论(0编辑  收藏  举报