luogu P8329 [ZJOI2022] 树
首先考虑一个暴力dp:设 \(f_{i,a,b,x,y}\),表示 dp 到第 \(i\) 个点,第一棵树前面有 \(a\) 个还没有儿子的非叶子节点,有 \(b\) 个已经有儿子的非叶子节点。第二棵树后面有 \(x\) 个还没有儿子的非叶子节点,有 \(y\) 个已经有儿子的非叶子节点。
这样的话状态是 \(O(n^5)\) 的,转移是 \(O(1)\) 的,似乎没有什么优化的空间。
我们先来考虑一棵树的情况,朴素的 dp 状态仍然是 \(O(n^3)\) 的。
这时候一般考虑容斥,一棵树的要求是:每个点 恰好 有一条出边,每个非叶子节点 至少 有一个儿子,每个叶子节点 不能 有儿子。
容斥应该就是在上面三个条件中找到一个来优化 dp 的状态。恰好 一类字眼想到的是二项式反演,但是这种 dp 一般还要加上一维状态所以不太行。而后面两种在两棵树上其实是对称的,所以不妨考虑拿第二个条件容斥。
设 \(f_{i,j}\) 表示到了第 \(i\) 个点,前面有 \(j\) 个点可以连的方案数。每个点前面的连边就是 \(j\) 种方案。接下来考虑每个点的状态:
- 这个点是叶子,那么有 \(f_{i,j}\to f_{i+1,j}\)。
- 这个点是非叶子,那么有 \(f_{i,j}\to f_{i+1,j+1}\)。但是这样不能保证 \(i\) 这个点至少有一个儿子,因此要减去它没有被连边的情况,即 \(-f_{i,j}\to f_{i+1,j}\)。
那么对一棵树的转移就结束了,两棵树的转移只需要将 dp 多一维表示另一棵树的状态即可。时间复杂度 \(O(n^3)\)。