0%

LOJ3102 「JSOI2019」神经网络

my submission on loj.ac

不难发现问题等价于:把每棵树划分成若干条链,把这些链拿来做圆排列,要求相邻的链不能来自同一棵树,求方案数。

假设我们已经把每棵树划分成了若干条链,并且确定好了链在圆排列中出现的方向(长度大于 $1$ 的链有两种可能的方向),求圆排列方案数。假设此时第 $i$ 棵树的点划分成了 $A_i$ 条链。

把环断开为序列,钦定序列的开头为第一棵树的 $1$ 号点所在的链。我们对序列的要求是:

  • 相邻的两条链不能来自同一棵树
  • 结尾的链不能来自第一棵树

首先我们确定每棵树内的点在序列中的相对顺序(也就是最终答案乘上 $(A_1 - 1)! \prod_{i=2}^m A_i!$)。

如果没有上面两个限制,方案数就是 $\frac{(\sum A_i -1)!}{(A_1 - 1)!\prod_{i=2}^m A_i!}$。

对于上面的两个限制,钦定一些同一棵树中相对顺序相邻的链粘在一起(或者钦定第一棵树中相对顺序在最右边的和序列的结尾粘在一起)进行容斥即可。

把方案数中的 $\frac{1}{(A_1 - 1)! \prod_{i=2}^m A_i! }$ 下放到每个 $A_i$ 头上(也就是在我们确定 $A_i$ 的时候就乘上相应的系数),那么计算总方案数就只需要知道 $\sum A_i$。把 $\sum A_i$ 作为状态进行 dp(或者把 $\sum A_i$ 作为生成函数的指数进行卷积)即可。

总时间复杂度 $O((\sum k_i)^2 )$。