放几个比较优(she)秀(pi)的\(LCT\)题。
老惯例,每一题代码由于一些未知缘由消失了(若是要的话私我好了,虽然会咕咕咕)。
嘴巴\(AC\)真香!算法
对黑色、白色各开一棵有根\(LCT\)。
若\(x\)点加入颜色\(c\)集合,则在\(c\)的那颗\(LCT\)上链接\((x,fa_x)\),在另外一棵上断掉父亲边。
查询时,首先判断根结点是否在当前颜色集合内。
若是在的话直接查整棵\(LCT\)。
不然走向右儿子,查询对应子树。
什么子树最大值啥的维护一会儿树信息,拿\(multiset\)搞搞就好了。spa
动态联通图?这种东西估计只有鸽子他们才会吧......
注意到边是任意定向,因此一个环等价于都能走,直接缩起来便可。
因此若是当前连边两点已经在一个联通块了,那么直接暴力缩点。资源
建\(SAM\),那么两个结点的\(LCA\)就是它们的最大\(lcp\)。
离线,依次加入左端点,那么它沿着\(SAM\)的\(fail\)树一路往上爬,遇到的全部右端点都有贡献。
这是\(LCT\)的经典应用,就是一个\(Access\)。
而且显然只有最靠左的右端点有用,因此\(LCT\)维护最小右端点便可。
最后获得了若干二元组,扫描线一遍完事。qt
显然每一个结点的答案只与/子树内战争个数\(sum\)/和//最大战争个数的子树/的战争个数\(mx\)//有关。
当\(mx > \lceil \frac{sum}{2} \rceil\)时,\(Ans = 2(sum-mx)\),不然\(Ans = sum-1\)。
一个直观想法就出来了,直接有根\(LCT\)维护子树最大值,每次\(Access\)更新答案。
吉老师:\(naive\)。
问题在于:每次\(PushUp\)须要知道子树大小,而知道子树大小须要\(Splay\)当前结点。
因此这题就变仙了。
直接相似\(LCT\)维护状态,对于知足\(mx> \lceil \frac{sum}{2} \rceil\)的儿子用重链链接,不然用轻链链接。
能够发现一条重要性质:爆跳父亲,重链个数不会超过\(log_2(deep)\)。
而后真相大白,所有暴力维护便可。io
维护重心是一个老的不行的套路了,使用启发式合并能够秒杀。
问题在于维护全部点到重心的距离和。
点分治?作梦吧你!
能够发现,对每个点维护联通块内的点到其的距离和至关浪费。
其实咱们只须要知道重心的该信息。
因此就只在重心维护这个信息,考虑重心移动时的转移,发现只须要再维护子树和就好了。
因为咱们须要支持\(Link\)操做的同时维护子树信息,因此依旧须要维护换根反转标记。class
显然染色操做就至关于\(Access\),而后考虑贡献。
咱们把减小量差分处理,那么对于重链链顶的子树,答案所有减小了\(1\)。
同时对于原来的重链儿子,其颜色会相对来讲增长\(1\)。
把原树给剖一下而后线段树区间修改直接维护便可。
如今有了换根操做,实际上是同样的。
能够发现,换根后进行一次染色,等价于先染色而后换根(反正那条链的颜色只有一个)。
因此就看成什么都没发生,直接换根。
因为如今根能够在查询点的子树内,因此这种状况加贡献也要特殊处理,稍微弄一下就好了。秒杀
\(n\)棵\(LCT\)是不可能的,这辈子都不可能的。
因为询问保证查询点必定在树上,因此把那些多余的点所有建出来是没有影响的。
因此惟一难办的操做就是更换生长结点了,此时须要集体换父亲操做。
不难想到,对于第\(i\)个生长结点,创建一个虚拟结点\(p_i\),把长在它下面的结点所有连在\(p_i\)上。
如今能够解决集体换父亲了,但如何放置这些虚拟结点使其知足对应包含关系?
咱们使用一种近乎疯狂的方式解决这个问题。
离线。
在算法开始前,咱们把\(p_i\)链接到\(p_{i-1}\)下面。
那么当碰到更换生长结点操做\(i\)的左端点时,直接把\(p_i\)链接到对应位置。
在该操做结束后,把\(p_i\)从新链接回\(p_{i-1}\)下面。
包含关系显然时刻都是对的。
而后查询答案涉及求\(LCA\)(可能为虚点),很棒的是\(LCT\)完美兹瓷该操做。查询