「ZJOI2022」树

d1t1.

ZJOI 的签到题,恐怖如斯。计数水平太低,我很抱歉。


首先记一个 \(f(S)\) 表示 \(T_1\) 的叶子/非叶子集合为 \(S\) 的方案数。如果我们求叶子集合为 \(S\) 的方案数是一件非常麻烦的事情,那么只有令 \(f(S)\) 表示 \(T_1\) 的非叶子集合为 \(S\) 的方案数。

当然直接求 \(f\) 也比较困难。考虑容斥,记 \(g(S)\) 表示非叶子结点集合是 \(S\) 的子集的方案数,容易得到:

\[f(S) = \sum_{T ⊆ S} (-1)^{|T|} g(S \backslash T) \]

其中,\(\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\) 有形式上的区别,本质相同),那么答案就长成:

\[\begin{aligned} \sum_{S} f_1(S)f_2(U \backslash S) &= \sum_{S} \sum_{T_1 ⊆ S} (-1)^{|T_1|} \sum_{T_2 ⊆ (U \backslash S)} (-1)^{|T_2|} g(S \backslash T_1)g(U \backslash (S \cup T_2)) \\ &= \sum_{S} \sum_{T_1 ⊆ S} \sum_{T_2 ⊆ (U \backslash S)} (-1)^{|T_1|+|T_2|} \prod_{i=2}^n \left(\sum_{j \in (S \backslash T_1)} [j<i] \right) \prod_{i=1}^{n-1} \left(\sum_{j \in (U \backslash (S \cup T_2))} [i<j]\right) \end{aligned} \]


做法 \(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\) 的定义见上。

\[\begin{aligned} \sum_{S} f(S)^2 &= \sum_{T_1 ⊆ S} \sum_{T_2 ⊆ S} (-1)^{|T_1|+|T_2|} g(S \backslash T_1)g(S \backslash T_2) \\ &= \sum_{T_1 ⊆ S} \sum_{T_2 ⊆ S} (-1)^{|T_1|+|T_2|} \prod_{i=2}^n \left( \sum_{j \in (S \backslash T_1)} [j<i] \right) \left( \sum_{j \in (S\backslash T_2)} [j<i] \right) \end{aligned} \]

这个基本上已经是完全态了。因为 \(\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: 容斥的合并。

posted @ 2022-05-18 09:48  SyadouHayami  阅读(97)  评论(0编辑  收藏  举报

My Castle Town.