题解 uoj424 【【集训队作业2018】count】

题解 uoj424 【【集训队作业2018】count】

\(\texttt{Solution}\)

题目要求统计长度为 \(n\),值域在 \([1,m]\) 且每种值至少出现一次的不同构的笛卡尔树个数

题目中要求笛卡尔树的构建是大根,且如有多个最大值取编号最小的

由于这个性质,我们要计数的笛卡尔树一定满足向左的链长不超过 \(m\)

这里向左的链长可以这样定义:

定义 \(f(root)\) 为一个括号序列,且 \(f(root)=(f(lson))f(rson)\),特别的 \(f(0)=\varnothing\)

那么向左的链长为 \(f(root)\) 的最大嵌套层数

我们发现 \([1,m]\) 的值每种至少出现一次很难处理

猜测对于 \(n\geq m\) 的情况均满足上述笛卡尔树存在构造使得序列里 \([1,m]\) 的值每种至少出现一次

事实上构造也很简单考虑在一个节点允许的值域范围为 \([1,v]\) 时,该节点取 \(v\)

左儿子递归 \([1,v-1]\),右儿子递归 \([1,v]\) 即可

由于向左链长不超过 \(m\) 显然正确

我们现在只需计数 \(n\) 个点的向左链长不超过 \(m\) 的二叉树数量即可

根据我们定义的括号序列,不难发现任意一个 \(n\) 对括号组成的合法括号序列对应一棵 \(n\) 个点的二叉树

即计数从 \((0,0)\)\((2n,0)\) 每次只能往右上/右下走且不经过 \(y=-1\)\(y=m+1\) 的路径条数

这个问题我们通过对称进行容斥

我们对于一条路径定义其“事件序列”,称碰到 \(y=-1\)\(a\) 事件,碰到 \(y=m+1\)\(b\) 事件

那么一条路径的时间序列为从左到右其碰到的所有事件形成的 \(ab\)

根据 Catalan 的相关套路,我们知道只有 \(y=-1\)\(y=m+1\) 时我们可以通过将起点关于直线对称,容斥出方案

此时我们再如此计算实际上得出的是事件序列里包含 \(a/b\) 的子序列的路径条数

对于存在子序列 \(ab/ba\) 的路径我们会算重,考虑减掉这部分贡献我们仅需继续对于另一条限制线对称

显然枚举的子序列均为 \(ababa\cdots/babab\cdots\) 型,且长度不会超过 \(\dfrac{2n}{m+2}\)

复杂度 \(O(n)\)

code

posted @ 2021-09-01 17:10  juju527  阅读(52)  评论(0编辑  收藏  举报