LCT 学习笔记

Part 1 基础操作

首先,最基础的 LCT 操作可以看 Oiwiki。我讲的肯定没有这上面好。

模板题

几个注意点:

  • 每次更改儿子之后需要 pushup。更改父亲,在维护子树信息时也需要进行修改。

  • findroot 是垃圾函数,大家不要去写。真的要写,每次搜索完必须要 splay 上来才能保证复杂度。

  • 对于权值标记,以及一些复杂的维护信息,需要考虑交换标记产生的影响。

  • 不要将 link 和 cut 函数在每道具体的题目中根据当前题意写不同的,保留最原始的 link 和 cut,这才会让你的代码不那么阴间。

  • 对于 splay 所有 向下走 的操作,主要是平衡树上二分的过程,在这之后,一定要将找到的那个位置 splay 上来,才能保证复杂度。


Part 2 套路题练习

好了,你已经学会 LCT 了,接下来做一点 基础套路题 来巩固吧!

[SDOI2008]洞穴勘测 (动态维护连通性&只有加边)

[TJOI2015]旅游(动态维护权值标记&较复杂的信息合并)

[NOI2014] 魔法森林(经典 LCT 与贪心的结合&动态维护边信息)

变化的道路(线段树分治&动态维护边信息)

[Cnoi2019]须臾幻境(妙妙题)

[USACO18FEB]New Barns P(动态维护直径)

EntropyIncreaser 与 动态图(动态维护割点&割边)

[BJOI2014]大融合(动态维护子树信息)

[SHOI2014]三叉神经树(定根 LCT&splay 上二分)

首都 (动态维护重心&splay 上二分)

详情可以参照这个 题单的前十七道题,我只是选了几道有代表性的出来。


Solution

关于这几道题中涉及的几个套路:

  • 维护边信息只需要新建一个点,然后连两条边即可。

  • 维护直径,需要用到的性质:新的直径的两个端点,一定是原来两颗树的总共四个端点中的两个。那么只要大力分讨最多六中情况即可。

  • 维护割点,只需要用 LCT 维护圆方树;维护割边,只需要维护边信息,每次区间打 tag。

  • 维护子树信息,需要存贮一个点 所有虚边 对应的儿子的子树信息,不同的地方在于 Access 和 link。

  • splay 上二分只要时刻记住 splay 的单调性是基于什么的,就不难。

  • 维护重心,关键在于重心的性质:以重心为根的树,根的所有儿子的子树大小不超过 n2


Part 3 进阶题练习

[SDOI2017]树点涂色

会注意到一操作实质就是 LCT 中 Access 的操作,然后一个点到根的路径的贡献就是其经过的虚边条数。

于是就可以直接用线段树在虚实边切换的时候维护子树信息。当然需要注意:splay 里的儿子不是树上的儿子,只有虚边才是真实的树边。

Code


[ZJOI2018]历史

题意转化十分小清新:给定每个点的 Access 次数,求最大的虚实边转化次数。

在手摸的过程中,我们能发现:每条边第一次被 Access 遍历到的时候,一定会产生一次贡献,而之后,却要考虑是否来自两个不同的城市的崛起。

我们将边的贡献丢到儿子上。根据 LCT 的性质,两次 Access 会在它们 Lca 处产生一次贡献。

对于每个点,它们之间是相互独立的,可以单独计算贡献。具体的,对于每个点,两次来自于不同子树的点作为起始位置的连续的 Access 会造成贡献(自己出发的位置也可以产生贡献)。当某一颗子树内部的次数很多,超过总数一半的时候,用插板法可以得到当前的最大次数,为 2×(aimaxai)。除此之外,我们都能够使得两两相邻的产生一次贡献。

那么我们现在就是需要维护每个点,所有儿子的子树的权值和,以及最大权值,然后支持单点修。

注意到一个很好的性质:当被修改后,所有维护信息变化的点,它们若是在修改前后都是第二种状态(最大值小于等于一半),答案也会加上相同的值;对于都是前后都是第一种情况的,如果贡献在最大值对应的子树上,答案不变,否则则是最大值对应的子树改变的情况,比较复杂。

在分讨的过程中,我们注意到,只有两种状态相互替换,或者第二种情况中最大值对应子树改变的时候,答案计算非常麻烦。

这里我们联想到 LCT 的虚实链切换次数是 log 次的,如果将这种转化对应到虚实链的切换,便能够使得复杂度正确。

于是我们就可以用 LCT 维护(雾),但是这个 LCT 和题意转化中的 LCT 不能混为一谈,我们只是利用 LCT 的性质分析出答案的计算方法,而后又发现这个东西可以利用 LCT 进行维护。

具体的,用实边表示第二种情况,那么所有答案的更改,与不变的实边无关,只需要在 Access 过程中进行虚实边判定即可。

代码调了三个小时,原因竟是 维护子树信息,splay 内调用子树大小应减去左儿子,也就是它的父亲的部分。

Code


这边还有一些和 SAM 有关的题,暂时咕咕咕。

top tree 的话 咕咕咕咕咕咕。


__EOF__

本文作者zjjws
本文链接https://www.cnblogs.com/zjjws/p/14617060.html
关于博主:我就是:究极的 Mad Scientist,凤—凰—院—凶—真da!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:这么屑的博主有什么声援的必要吗?
posted @   zjjws  阅读(263)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示