zoukankan      html  css  js  c++  java
  • 一篇打脸文

    打脸了...Splay其实有两种用法,第一个是常数奇大的平衡树

    而第二个就厉害了,Splay可以对区间进行操作

    具体是怎么个意思呢,我们来看这样一件事情

    对于一个数列,我们用Splay维护它的下标

    然后我们进行下面的Split操作

    1.将l-1旋转到根

    2.将r+1旋转到l-1的右儿子

    令a为r+1的左子树

    然后我们惊奇的发现a这棵子树表示了区间[l,r]

    然后...我们就可以对a为所欲为了

    当然要注意,l-1指的是数值,而不是点,所以我们需要借用Splay作为平衡树时的一个函数:find()来找到l-1存在哪个位置

    然后...我们就可以为所欲为啦

    1. 插入、删除:

    对于插入操作,我们可以将x转到根部,再将x+1转到x下方然后在x+1的左子树中插入新节点即可。 
    那么类似的对于删除,我们也可以先将x-1转到根部,x+1转到根下方,那么x就是x+1的左子树,直接删除即可~

    2. 询问:

    对于询问区间(x,y)的最值,只需将x-1转到根,然后将y+1转到x-1的下方,于是我们需要维护的区间就在y+1的左子树的所有点的集合里了,直接输出节点信息即可。

    3. 翻转、区间增加:

    和询问类似,先将x-1转到根,然后将y+1转到x-1的下方,然后对y+1的左子树打标记即可~,注意及时更新标记。

    4. 滚动:

    可以发现,滚动某个区间就等价于交换区间的两部分,我们设这个中点为z,那么我们的目的就是交换(x, z) 和 (z+1, y), 我们可以先将z转到根,然后将y+1转到z的下方,于是y+1的左子树就对应了区间(z+1,y)然后我们将这一段切下来,继续将x-1转到根,再将x转到x-1下方,最后将区间(z+1, y)接到x-1的左边即可。

    最后一个问题,怎么输出呢?

    注意到我们建Splay的时候,其实它的中序遍历就是原数组,我们写一个递归的print()函数就可以了...

    之前还一直以为Splay只是一个平衡树...

    真是Naive!

  • 相关阅读:
    javascript 模板系统 ejs v2
    三国观后感
    《非诚勿扰》乐嘉老师送给男生女生的话:
    正则学习笔记6
    硬链接和符号链接
    javascript 模板系统 ejs v1
    javascript模板系统 ejs v3
    程序员编程艺术:第八章、从头至尾漫谈虚函数
    程序员编程艺术第十一章:最长公共子序列(LCS)问题
    编程艺术第二十三~四章&十一续:杨氏矩阵查找,倒排索引关键词Hash编码
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/7979369.html
Copyright © 2011-2022 走看看