题解 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)\)