Luogu7570 「MCOI-05」多宇

题意 : 给出一棵 个点的外向树 ,以及 条额外的边,满足加入这些边之后图 是 DAG。

对于点对 ,若在 不能到达 ,但是在 可以到达 ,则称点对 是好的。

每次询问给出 ,求有多少对好的 满足

,时限


@newbiewzs 题解的详细版。

对于额外边 ,将 标记为“关键点”。记关键点集合为

观察好对子 的分布。

在固定 时,若 是好的,且 ,则 是好的。

这说明 的分布必然是若干不交的 的子树(称作好子树)。不难进一步发现,这些子树的根都是关键点。


对于每个好的对子 ,在所有可能的路径 中,都必然有至少一个关键点。取某个关键点作为“统计点”,这样我们才能对贡献转置。

根据如上观察,我们取 所在“好子树”的根作为统计点 ,这样是唯一的。

考虑如何判定 是否满足“是好的,且统计点为 ”。

首先有必要条件 ,否则 不是好的。

然后,为了保证统计点,一个显然的必要条件是,。但这不充分,我们称满足该条件的 中转点

不难发现,中转点都是 的祖先,那么深度最小(是其他中转点的祖先)的中转点就是统计点了。

对关键点 ,记 使 那么 就是“统计点为 ”的充要条件。

再将 纳入考虑,注意到 ,前者可以等价为

于是改记 使


考虑如何求 ,使用转置。记 使 显然, 互为转置。

是简单的传递闭包。

对于 ,先用传递闭包处理 “”,然后用 dfs 序和树形 DP 处理 “” 和 “使”。

使用 bitset,时间 ,空间

  • 卡常技巧

    • 不要用 [] 操作 bitset,而要使用 set,reset,test 等函数,常数小很多。

    • 树形 DP 可以转为 dfs 序上的问题。


接下来考虑如何回答询问。

为了方便处理,将条件 拆成

对于每个 ,上述式子都容易用前缀和搞定。

总时间复杂度 ,空间复杂度(若离线)