「ZJOI2022」树
d1t1.
ZJOI 的签到题,恐怖如斯。计数水平太低,我很抱歉。
首先记一个 \(f(S)\) 表示 \(T_1\) 的叶子/非叶子集合为 \(S\) 的方案数。如果我们求叶子集合为 \(S\) 的方案数是一件非常麻烦的事情,那么只有令 \(f(S)\) 表示 \(T_1\) 的非叶子集合为 \(S\) 的方案数。
当然直接求 \(f\) 也比较困难。考虑容斥,记 \(g(S)\) 表示非叶子结点集合是 \(S\) 的子集的方案数,容易得到:
其中,\(\displaystyle g(S) = \prod_{i=2}^n \left(\sum_{j \in S} [i<j] \right)\)。两个式子的意义都非常显然,不再赘述。当然 \(1 \in S,T\),虽然不在也行没有影响。
接下来的问题是,我们只处理掉了一棵树,还有一棵树怎么办?
容易发现另外一棵树的贡献形式与第一棵树类似。那么记 \(f_c,g_c\) 是 \(T_c\) 中的 \(f,g\)(容易发现 \(g_1,g_2\) 有形式上的区别,本质相同),那么答案就长成:
做法 \(1\):
因为一个点 \(p\) 只会在一棵树内成为叶子,这个形式已经可以直接容斥了。
那么分四类讨论:
- \(p \in S\),但 \(p \not \in T_1\);
- \(p \in T_1\);
- \(p \not \in S\),且 \(p \not \in T_2\);
- \(p \in T_2\)。
注意到点 \(1,n\) 很烦,我们暂先将这两个点排除。
分析 \(g_1,g_2\) 的结构,我们需要知道 \(T_1\) 非叶子结点个数的前缀和和 \(T_2\) 非叶子结点个数的后缀和。
那么定义 \(dp_{i,j,k}\) 表示,现在考虑了前 \(i\) 个点,\(T_1\) 内已经出现了 \(j\) 个非叶子结点(含点 \(i\)),\(T_2\) 内编号在 \([i+1,n]\) 的非叶子结点个数为 \(k\)。
然后这个转移形式比较显然,对着做就好了。答案为 \(\displaystyle \sum_{i} dp_{n-1,i,1} \times i\),因为 \(T_1\) 中 \(n\) 是叶子,随机连一个钦定的非叶子结点就好了。
做法 \(2\):
这个形式好**丑啊!!
通过打表发现,\(f_1(S) = f_2(U \backslash S)\)。代数证明可以看知乎题解。
那么问题就变成了两棵树按 \(T_1\) 的方式生成。求两棵树叶子集合相等的方案数。
做法 \(2.1\):
那么现在就是求 \(\displaystyle \sum_{S} f^2(S)\)。这个形式一样的展开,比上面那个方法好写。
还是写一下,\(f,g\) 的定义见上。
这个基本上已经是完全态了。因为 \(\prod\) 后面带的式子上下角标一样了,我们可以合并。
定义 \(dp_{i,j,k}\) 表示处理了 \(i\) 个点,当前的 \(|T_1|=j,|T_2| = k\)。我们从小到大加入点,系数就不必重算一次 \(\prod\) 内的 \(\sum\) 了。
那么,仍然是分类讨论:
- \(p \not \in S\);
- \(p \in T_1 \cap T_2\);
- \(p \in T_1, p \not \in T_2\);
- \(p \in T_2, p \not \in T_1\);
- \(p \not \in T_1 \cup T_2\)。
顺着系数转移就好了。记 \(p = dp_{i,j,k} \cdot jk\)(下面的转移与上面的转移一一对应):
- \(p \to^+ dp_{i+1,j,k}\);
- \(p \to^+ dp_{i+1,j+1,k+1}\);
- \(p \to^- dp_{i+1,j+1,k}\);
- \(p \to^- dp_{i+1,j,k+1}\);
- \(p \to^+ dp_{i+1,j,k}\)。
其中 \(a \to^+b\) 表示 \(b \gets b+a\),\(a \to^- b\) 表示 \(b \gets b-a\)。
做法 \(2.2.1\):
那么考虑定义 \(dp_{i,j,k_1,k_2}\) 表示前 \(i\) 个点里,有 \(j\) 个共同的叶子,\(k_1\) 表示 \(T_1\) 内为叶子但在 \(T_2\) 内不是叶子,\(k_2\) 同理的方案数。可以分类讨论转移,时间复杂度是 \(O(n^4)\) 的。
做法 \(2.2.2\):
(为保护当事人隐私,已将头像进行模糊处理。)
那我们就不考虑 \(j\)。再定义 \(dp_{i,k_1,k_2}\) 表示考虑了 \(i\) 个点,\(k_1\) 表示 \(T_1\) 内有 \(k_1\) 个非叶子结点的度还没有填。
那么只有两个转移,一个是 \(i\) 为叶子结点,另一个就是不是叶子结点。转移显得更简单了。相应的复杂度变高了,时间复杂度 \(O(n^5)\)。
做法 \(2.2\):
答案是可以通过奇怪的生成函数技巧优化 \(2.2.2\) 求得和做法 \(2.1\) 一模一样的转移式子。
Code(做法 2.2.1);
Code(做法 2.1/2.2)。
Key observation: 容斥的合并。