Loading

CF1704H Game of AI

场上直接写了下面的做法,但是以为除叶子外树上的一个点最终标号不能是自己,于是一直调不出来,下分了 /ll

感觉 G 很简单,亏大了

题意

对于每个序列 \(a\) 满足 \(1 \le a_i \le n\)\(a_i \neq i\),以及一个排列 \(p\),一个 bot 的游戏定义为:
开始每个位置 \(i\) 都被 \(i\)\(\rm bot\) 占领。
在第 \(i\) 轮游戏中,\(p_i\)\(\rm bot\) 如果在游戏中存在,那么他会占领 \(a_{p_i}\) 号位置,原先占领 \(a_{p_i}\) 号位置的 \(\rm bot\) 将不再占领那个位置。
如果一个 \(\rm bot\) 不再占领任何一个位置,那么该 \(\rm bot\) 将会退出游戏。
设最后占领第 \(i\) 个位置的 \(\rm bot\)\(b_i\)。对于 \(1 \le n \le N\),求 \((a,b)\) 的个数。

数据范围:\(1 \le N \le 10^5\)

题解

我们对于每个序列 \(a\) 计数 \(b\) 的个数。\(a\) 形成了一颗基环树。

首先考虑对于一颗树计数:

\(F(x)\) 表示对于一棵大小为 \(x\) 的树的 \(b\) 的个数的 \(\rm EGF\)\(G(x)\) 表示对于一颗大小为 \(x\)\(b_{root} = root\)\(b\) 的个数的 \(\rm EGF\)

首先考虑假设 \(b_{root} \neq root\),那么根节点可以取任意一个子节点的标号,于是:

\[F(x) = G(x) + x \sum_{i \ge 1} \frac{iF(x)^i}{i!} = G(x) + xF\exp(F) \]

然后考虑 \(b_{root} = root\) 的情况。在这种情况下,要求根节点所有子节点都被踢出了游戏,也就是 \(b_{son} \neq son\)。因此:

\[G(x) = x \exp(F - G) \]

这个东西可以用分治 \(\rm FFT\) 分治的时候同时记录下 \(\exp(F-G)\)\(\exp(F)\)

也可以用牛顿迭代:\(F = x\exp(xF\exp(F)) + xF\exp(F)\)

然后考虑对于单个基环树计数。

对于环上的一个节点 \(x\) 分类讨论。设 \(y\)\(x\) 在环上的上一个节点。

  1. \(b_x = y\):对于环上的所有点不能都满足 \(b_x = y\),由于子树是什么不重要,因此生成函数为 \(x\exp(F)\)
  2. \(b_x \neq x, b_x \neq y\):那么取的是一个 \(x\) 的子节点,没有限制,生成函数为 \(F - G\)
  3. \(b_x = x\):那么 \(x\) 的上一个节点 \(y\) 必然满足 \(b_y \neq y\)。这个时候我们可以把这个节点和上一个节点合并起来,看成一个大节点。这个大点的生成函数就是:\((x\exp(F) + F-G) \times G\)

首先总情况数就是这三种情况的生成函数的和,设和为 \(T\),然后连成一个环,其生成函数就是 \(\sum_{i \ge 1} \frac{T^i}{i} = \ln(1-T)\)

然而这样直接连可能不合法,因此容斥掉环上所有点都满足 \(b_x = y\) 的情况,再容斥掉环上只有一个点的情况即可。

算出单个基环树的答案后,直接 \(\exp\) 就能得出答案。

我的实现中树的答案是用分治 FFT 求的,时间复杂度 \(\Theta(n \log^2 n)\),如果用牛顿迭代就是 \(\Theta(n \log n)\)

aclink

posted @ 2022-08-01 09:46  zhoukangyang  阅读(524)  评论(0编辑  收藏  举报