BSOJ8160口胡

\(f[i]\) 表示和第 \(i\) 个外挂相交且右端点大于第 \(i\) 个外挂中,右端点最大的外挂,\(g[i]\) 表示右端点满足上述条件中次大的外挂。

如果他不删除外挂,那么直接按着 \(f[i]\) 倍增,然后跳到某个外挂右端点大于 \(t\) 即可。

具体实现可以将 \(i\) 看做一个 \([i,i]\) 的外挂然后按照上述方式维护。

容易发现路径一定是一段 \(f\) 一段 \(g\) 最后再一段 \(f\)

于是按照 \(f\)\(g\) 建树,先跳到被 ban 外挂的下面,然后到另外一颗树上面跳到某个节点的 \(f\) 不是被 ban 节点为止,然后回到 \(f\) 继续跳。

这样子是 \(O((n+m)\log n)\) 的。实际上可以做到线性。

首先你需要知道四毛子可以线性 \(k\) 级祖先。并且四毛子可以线性树上并查集。

然后跳到被 ban 外挂的下面可以用四毛子。

然后在 \(g\) 上面跳到非 \(f\) 所在节点,可以使用并查集。具体为将所有 \(f\) 是被 ban 外挂的节点连接其父亲即可。

然后问题变为给定 \((u,k)\) 表示询问 \(u\) 最浅的祖先满足其右端点不小于 \(k\)

\(k\) 从小到大排序,令 \(k\) 增加时重复在 \(g\) 上类似的操作即可。

复杂度 \(O(n+m)\)

清空可以使用时间戳。

posted @ 2022-09-24 17:00  Prean  阅读(25)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};