从理解斜二倍增,到放弃斜二倍增
CommonAnts · · 算法·理论
::::warning[严正声明]{open} 对于梦熊联盟,以及其实际控制人和主要管理人员实际控制的其它机构,禁止任何人于正在临时或长期参与其任何活动期间,以任何直接或间接方式转载,引用,使用,传播或展示:本人在2024年5月或以后创作的任何内容或片段,包括所有声明为公开发表的内容在内!学生或教师本人自行阅读学习为被允许的例外情况,但此授权不包括在上述实体活动期间在其平台上进行转载,引用,传播等。 ::::
公开资源推荐和征集:
- 【持续更新】网络资源推荐;部分网友题单博客和技巧知识总结
- 【持续更新】OI 中的小资源合集[utilities]
- 《算法问题教学笔记》计划(基于竞赛,可自学的算法设计教材纲要探讨)
- OI 教学研究当前的若干具体问题
什么是斜二倍增?我看不懂斜二倍增怎么办?
问题: 我有一棵有根树,想支持在线动态
在下文中,为了简便,我们设定:查询的信息基于点权而非边权。
传统解法:
- 直接上LCT:但是难写且常数大。
- 树剖:因为动态加点得随机选重儿子,但是如果数据不随机又得上平衡调整,然后你发现自己发明了LCT。
- 每
\log n 层树分块/取关键点:这思路能做,但还是没那么好写。 - 树上倍增:好写好用,但是每个点要
O(\log n) 预处理,怎么办?
我们考虑怎么优化树上倍增。树上倍增预处理的信息总共
尝试直接让线段树上树。方便起见,我们取完美线段树(区间长度都恰好是
也就是说,对于每个树上的点
可以发现,这等于:对于每个点
这样,我们已经把树上倍增几乎变成线段树的
但还有一个小问题:线段树虽然总复杂度是
斜二倍增
这其实很简单:我们把每个线段树区间的定义从两个子树区间的并,改成:两个子树区间的并后面再多加一个点。也就是形如:
这个线段树称为斜二进制线段树。这样每个点存的区间数都变成了严格的
之后的用法就和普通倍增一样,具体代码可以参考介绍博客 - UT。
我不想学斜二倍增!普通倍增能代替吗?
其实可以,直接按前文所述对倍增添加一个上限
那么怎么解决同深度点太多时复杂度不对的问题呢?
方法一. 如果问题可以换根,可以先遍历树找一个好的根,总存在一个根使得每个点深度的
证明和构造思路:考虑对树进行黑白染色,取黑/白根时所有同色(或者异色,看深度定义)点的深度全为奇数。所以递归到较小颜色为偶数的情况里选取,然后继续递归即可。
方法二. 这个更简单,而且通用:我们一开始均匀随机选取一个全局的
证明思路:这相当于把所有下标和线段树区间整体平移了一下,容易发现不影响线段树的复杂度。但这会让每个点
\pmod{2^{\lceil \log n \rceil}} 都变成均匀随机的,而均匀随机整数的\mathrm{lowbit} 期望(平均)等于1 。所以期望复杂度正确。
缺点:倍增数组不定长,内存分配可能是个问题。不过出题人不刻意卡的话 vector 即可。卡就手动分一下。
因为本来就差不多(随机化和确定性的区别)目前可以完全代替斜二倍增,适合不想学新代码的选手。
题外话:对于有些问题倍增
O(n\log n) 个信息是必要的。比如树上求两个路径的最长公共前缀二分哈希时,必须要任意两个点都能走相同长度。
我普通倍增也不想学了
树分块:每
代码
随机偏移倍增(方法二)求 LCA 的核心代码(我写的比较繁杂,可以根据你自己的倍增代码修改):
和普通倍增唯一区别是倍增步数取了个
int L(int x){return __builtin_ctz(x+C);} // lowbit位数。其中C是全局预处理常数,在O(n)值域随机的一个正整数
int B(int x){return 31-__builtin_clz(x);} // 二进制最高位数
// dep:深度 f[i][j]:i的2^j级祖先,其中j<=min(B(dep[i]),L(dep[i]))
int lca(int u, int v){
if(dep[u]<dep[v])swap(u,v);
int dd=dep[u]-dep[v];
while(dd){ // 跳到dep[u]==dep[v]
int di=min(L(dep[u]),B(dd));
u=fa[u][di], dd-=(1<<di);
}
for(int i=B(dep[u]);i>=0;){
int di=min(min(B(dep[u]),L(dep[u])),i);
if(fa[u][di]==fa[v][di])
i=min(i,di-1); // 不用再尝试>=di的了
else
u=fa[u][di], v=fa[v][di];
}
if(u!=v)u=fa[u][0],v=fa[v][0];
return u;
}
坚决反对与虎谋皮,以营销炒作的方式“推广知识”,破坏社区秩序的行为!
坚决反对通过向部分不懂算法的家长/教练危言耸听,吹嘘特定知识重要性,强迫学生学习,破坏教学秩序的行为!
坚决支持建设高质量公开资料推荐平台和日报刊物平台!
对于梦熊联盟,以及其实际控制人和主要管理人员实际控制的其它机构,禁止任何人于正在临时或长期参与其任何活动期间,以任何直接或间接方式转载,引用,使用,传播或展示:本人在2024年5月或以后创作的任何内容或片段,包括所有声明为公开发表的内容在内!学生或教师本人自行阅读学习为被允许的例外情况,但此授权不包括在上述实体活动期间在其平台上进行转载,引用,传播等。