当前位置: 首页 > news >正文

splay

s p l a y splay splay 是一种平衡树,但是并不完全平衡。

它凭借一系列操作使得树趋近于平衡,所以与 A V L AVL AVL 比起来,时间可能没那么快,但是 s p l a y splay splay 可以应用到的地方很多,比如说区间翻转,这是 A V L AVL AVL 无法做到的。

并且LCT要用到splay。

规定

  • t r e e [ x ] . s o n [ 0 / 1 ] tree[x].son[0/1] tree[x].son[0/1] 表示 x x x 的左右儿子是谁。
  • t r e e [ x ] . s i z e tree[x].size tree[x].size 表示以 x x x 为根的子树大小。
  • t r e e [ x ] . f a tree[x].fa tree[x].fa 表示 x x x 的父亲节点。

原理

旋转

s p l a y splay splay 也是利用旋转来维护的,它旋转时传的是儿子节点,然后将儿子节点转到父亲节点。

旋转时有两种情况,一种是我是你的左儿子,一种是我是你的右儿子,但其实两种情况分析起来本质上都差不多,可以打在一起。(不用像 A V L AVL AVL 一样分开)

代码

int pdd(int x) { return tree[tree[x].fa].son[1] == x; }//x是它父亲的哪个儿子
void rotato(int x) {
    int y = tree[x].fa, z = tree[y].fa, p = pdd(x);
    tree[z].son[pdd(y)] = x;
    tree[x].fa = z, tree[y].fa = x;
    tree[y].son[p] = tree[x].son[p ^ 1], tree[tree[x].son[p ^ 1]].fa = y;
    tree[x].son[p ^ 1] = y;
    updata(y), updata(x);//更新信息
}

splay

s p l a y splay splay 肯定有 s p l a y splay splay 操作。

s p l a y ( x , y ) splay(x, y) splay(x,y) 就是用来将 x x x 转成 y y y 的儿子。

用到了旋转操作。

代码

bool pd(int x, int y) { return tree[x].fa != y; }
void splay(int x, int goal) {
    push(x);//因为有时候要区间翻转,这个用来用来下传翻转标记,如果题目没有翻转可以不用
    for (int y; pd(x, goal); rotato(x)) {
        y = tree[x].fa;
        if (pd(y, goal))//用来加快程序速度,删除对程序正确性不会有任何影响
            rotato(pdd(y) == pdd(x) ? y : x);
    }
    if (!goal)
    	root = x;
}

查找,删除的操作都可以参照AVL来做,所以不再叙述。(可以看看我的另一篇博客)

翻转

我们来看看翻转操作如何实现。

我们假设要将区间 l , r l, r l,r 翻转,我们设 l ′ , r ′ l',r' l,r 分别为 l l l 位置的左边, r r r 位置的右边。

则我们可以先将 l l l 节点 s p l a y splay splay 到根节点,再将 r r r 节点 s p l a y splay splay 到根节点的右儿子。

此时 r r r 节点的左子树就是我们要翻转的区间。

由于平衡树的性质,我们只需要将该子树的每个节点的左右儿子交换,便可翻转整个区间。

此时我们前面的 s p l a y splay splay 中的 p u s h push push 就是用来将翻转标记翻转下来。

代码

void push(int x) {
    if (tree[x].fa)
        push(tree[x].fa);
    pushdown(x);
}
void reverse(int l, int r) { //此时的l,r就是l',r'
    splay(l, 0), splay(r, l), tree[tree[r].son[0]].flag ^= 1;
}

此时 s p l a y splay splay 的基本操作就讲完了。

相关文章:

  • 这是从零在独自开开发,将是副业赚钱最好的平台!
  • 基于 oss 框架的音频驱动
  • 基于matlab使用机器学习和深度学习进行雷达目标分类
  • LeetCode - 1109 - 航班预定统计
  • Rust编码的信息窃取恶意软件源代码公布,专家警告已被利用
  • typora每次复制文档都要附带图片文件夹?学会配置gitee图床
  • 离散数学 课时一 命题逻辑的基本概念
  • Typescript - 类型守卫(typeof / in / instanceof / 自定义类型保护的类型谓词)通俗易懂详细教程
  • 【Android -- 每日一问】现在 Android 怎么学?学什么?
  • 蔚来日常实习收获
  • 【C++入门】命名空间,输出输入,缺省参数,函数重载
  • [oeasy]python0078_设置索引颜色_index_color_ansi_控制终端颜色
  • day3——有关java运算符的笔记
  • 二、Linux文件 - Open函数讲解实战
  • Matlab 点云迭代加权最小二乘法拟合平面(抑制噪声)
  • XCP实战系列介绍08-基于Vehicle Spy进行XCP测量的工程配置详解
  • 某程序员去华为面试,因为错了一道题而被淘汰
  • Mysql 数据类型
  • 尚医通(八) Nginx
  • npoi word 里面厂家操作
  • 尹锡悦涉嫌发动内乱案第二次庭审21日举行,媒体获准拍摄
  • 儿童阅读空间、残疾人友好书店……上海黄浦如何打造城市书房
  • 2025年青年普法志愿者法治文化基层行活动启动
  • 习近平会见柬埔寨太后莫尼列
  • “替父追债被判寻衅滋事案”从犯获国赔,该案司法机关共赔偿217万元
  • 青创上海-2025浦东徒步行倒计时1天,明日浦东世博文化公园不见不散