考虑用 $n \log n$ 时间还原出一种拓扑序。将 $1$ 节点设为根节点,对于每个加入的节点 $x$ ,对于一个点 $p$ ,如果前缀集合不加入它则查询为 false ,加入为 true ,说明 $p$ 是 $x$ 儿子,将点 $x$ 插入到 $p$ 前。最后构造出拓扑序。
按照拓扑序从后向前枚举每一个点 $x$ ,维护一个当前根节点集合,同样地,如果多一个点 $p$ 从 false 转变为 true ,则说明 $(x, p)$ 有边。
二分查询。
查看代码
1 |
|
\begin {array}{c} \mathfrak {One Problem Is Difficult} \\\\ \mathfrak {Because You Don't Know} \\\\ \mathfrak {Why It Is Diffucult} \end {array}
考虑用 $n \log n$ 时间还原出一种拓扑序。将 $1$ 节点设为根节点,对于每个加入的节点 $x$ ,对于一个点 $p$ ,如果前缀集合不加入它则查询为 false ,加入为 true ,说明 $p$ 是 $x$ 儿子,将点 $x$ 插入到 $p$ 前。最后构造出拓扑序。
按照拓扑序从后向前枚举每一个点 $x$ ,维护一个当前根节点集合,同样地,如果多一个点 $p$ 从 false 转变为 true ,则说明 $(x, p)$ 有边。
二分查询。
1 | #include "C.hpp" |