线段树3 线段树优化建图

线段树优化建图可以用 \(O(\log n)\) 的时间做到将一个点一个区间内所有点连边。

它不能直接做到将一个区间内所有点一个区间内所有点连边。如果需要做到,则需要将区间等价变形成若干点,使得这些点的答案合并起来恰好是区间的答案。要做到这一点,需要根据具体题目发现性质。

怎么优化建图呢?将区间转成线段树上的若干个节点,把一个叶子向这些节点连有向边,表示选了它就得选它们;同时线段树上的父亲向两个儿子的有向边也是图的一部分。

eg1. 炸弹

这是一道模板题。详细题解

eg2. Intrinsic Interval

暴力怎么写呢?肯定从当前的区间 \([l,r]\) 出发,求出 \(vl=\min_{i\in [l,r]} a_i,vr=\max_{i\in [l,r]}a_i\),将 \([vl,vr]\) 映射到下标上,得到新的 \([l',r']\),如此迭代,最终得到的就一定是这个区间。

实质上我们每次要得到一个 \([l,r]\) 指向 \([l',r']\) 的方式。但是上面已经说过,区间指区间是不能实现的;除了把 \([l,r]\) 拆成点,我们别无选择。但是难道拆成 \(i\in [l,r]\)?显然这样得不到答案。为了体现区间的特质,我们考虑将其拆为 \([i,i+1],i\in [l,r-1]\)。这样各自的答案区间(\([l'_i,r'_i]\))并起来就是 \([l',r']\);每个 \([i,i+1]\) 看成一个点 \(i\) 就行了。线段树上还是父亲指向儿子。建图+缩点,得到一张 DAG,DAG 上递推出每个点的区间。查询时采用线段树区间查询。

posted @ 2022-08-03 20:25  pengyule  阅读(40)  评论(0编辑  收藏  举报