【题解】CF983E NN country 贪心 倍增 主席树

题目链接

*倍增一般解决的问题是找 111100000 最右边的 1 或找 000001111 最右边的 0。

发现题意拍到序列上即给定若干条线段,若干次询问覆盖区间 \([l,r]\) 最少需要多少条线段。

对于序列上的问题,可以通过倍增优化贪心令 \(f[i][j]\) 为从点 \(i\)\(2^j\) 次贪心选择能覆盖到的最远点,在 \(O((n+q) \log n)\) 的时间内解决。

对于树上我们考虑将点 \(u\) 到点 \(v\) 的路径差分成 \(u\to lca\) ,\(lca\to v\) ,每个点维护从点 \(i\)\(2^j\) 次贪心选择能覆盖到深度最浅的祖先。

对于前一段从下到上 \(u\to lca\) 可以直接在倍增表上跳,对于后一段考虑从下往上倍增 check(类似 P7518 [省选联考 2021 A/B 卷] 宝石 从上到下的 \(trick\) )。

具体地:一种朴素的做法即考虑二分后面一段向上跳的距离,令 \(anc\) 为最终跳上去的点,check 是否存在一种方案使得可以可以覆盖点 \(u\) 到点 \(anc\) ,二分 + 向上跳的复杂度为 \(O(\log^2 n)\) ,但是这个复杂度太弱智了,因此可以直接考虑倍增这样的复杂度为 \(O(\log n)\)

考虑合并,我们要解决的问题即是否存在一条线段满足一端在以 \(a\) 为根的子树内,另一端在以 \(b\) 为根的子树内,发现是一个二维数点类状物,并且要求在线询问,因此可以直接主席树维护。

这样总的复杂度为 \(O(n\log n + q\log ^2n)\)

代码记录

树上路径覆盖的双射:

总体思想:将路径差分成 \(u\to lca\) ,\(lca\to v\) ,\(lca\)

  • 一条路径,覆盖点 \(x\) 的充要条件为一端在以 \(x\) 为根的子树内 / 一端在以 \(x\) 为根的子树外或 \(x\) 是其 \(\text{LCA}\) ,即:对于路径 \((a,b),a\in T(x)\) 只要 \(\text{LCA(a,b)}\not\in T(x)\)\(\text{LCA(a,b)}=x\) 即可。

  • 一条路径同时覆盖点 \(x,y\)\(x,y\) 不是祖先关系则当且仅当路径两个端点分别在以 \(x\) 为根的子树中,以 \(y\) 为根的子树中,如果为祖先关系则需要满足一端在深度较深的子树内,一端在 \(pre\) 子树以外。

posted @ 2021-09-06 16:47  Themaxmaxmax  阅读(128)  评论(0编辑  收藏  举报