TCRabbitPuzzle
数轴上有三个相同的点 ,你需要通过恰好 次操作把点移动到 ,求方案数。
每次操作,选择两个点,将一个点移动到另一个点轴对称的位置,但是只能越过一个点,并且不能出现两个点位置相同。
。
分析一下这个操作的性质。
如果是两边的点对称到中间,那么只有一种对称方式,如果是中间的对称到两边,那么有两种,并且每个操作都有一个对应的逆操作,那么可以把原问题变成一个图上行走问题。
画出来是一棵二叉树,并且由于每个点的父亲唯一而且互不相同,也就是每种状态不可能在树上出现多次。
问题转化为给出二叉树上的两个点,求一个游走到另一个的方案。
跑出 LCA,那么有效的信息只有两个点到 LCA 的距离以及 LCA 到根的距离。
我开始的想法是,注意到每次行走,都有一种方案向终点走一步,两种方案远离,所以组合数简单算一下,容斥掉跳到根上面的方案即可。
但是这样是寄的,因为如果已经到达了答案,那么三种走法都是远离,贡献难以计算了。
由于要限制不能到根上面,因此枚举一下走到深度最浅的点 。
路径总体可以看成是 ,只不过在这条路径的中间,可以在一个点原地游走一下然后再去下一个点。
例如对于 这一段,考虑 到其父亲前面的一段,那么就是向下走两种方案,向上一种,然后需要满足一个卡特兰数的限制。
后半段也是同理的,会发现走 的次数是确定的,行走的方案数就是 这条路径长度个卡特兰数卷起来,这个之前出现过了,可以看成是加了 个右括号将他们分隔开来,然后左边放 个左括号。
总复杂度 。
1 | int main() { |