首页 > 其他分享 >浅谈可持久化栈的实现

浅谈可持久化栈的实现

时间:2023-01-06 19:12:19浏览次数:55  
标签:持久 浅谈 val 化栈 tot fa cur

可持久化栈

看到网上基本没有说得很详细的,所以我来讲一讲。

一种好的方法是直接用可持久化数组(线段树)来模拟栈,单次插入/删除时间复杂度 \(O(\log n)\),空间复杂度 \(O(n \log n)\)。

这种方法也具有一定的优势——可以随机访问栈中元素,不过一般情况我们不需要可持久化栈支持这个操作。如果是这样的话,可持久化栈的单次插入的时间复杂度可以优化为 \(O(1)\),空间复杂度也可以变为 \(O(n)\)。

例题:ABC273E - Notebook

插入操作

其实可持久化栈的本质就是用链表模拟栈,一个节点代表一个版本的栈顶,这些节点串联起来就得到了整个栈。

tot++;
val[tot] = x;
fa[tot] = cur;
cur = tot;

上面是向栈中插入新的元素 \(x\),并同时生成新版本的方式。

tot:代表总结点数。

val[i]:节点 \(i\) 的值。

fa[i]:节点 \(i\) 的前驱。

cur:当前操作栈的栈顶。

删除操作

如果要更好的解释可持久化栈,你可以把它理解为每一个栈依赖于另一个版本的栈(就是 fa[i]),那个栈有依赖于一个版本的栈,最后直到空栈。这种依赖关系形成了一棵树。

cur = fa[cur];

这步更加简单,往回跳一个版本即可。

版本跳跃

如果希望栈立刻回到之前的某一个版本的栈顶:

cur = pos[x];

pos[i]:第 \(i\) 次操作后 cur 所在的栈顶。

pos[i] = cur; // 每次 插入/删除 操作结束后

ABC273E 模板题代码:

#include <bits/stdc++.h>
using namespace std;
int q, x, y, z, tot, cur, val[500005], fa[500005];
unordered_map<int, int> page;
char opt[7];

int main()
{
    scanf("%d", &q);
    while (q--)
    {
        scanf("%s", opt);
        if (opt[0] == 'A')
        {
            scanf("%d", &x);
            tot++;
            val[tot] = x;
            fa[tot] = cur;
            cur = tot;
        }
        else if (opt[0] == 'D')
            cur = fa[cur];
        else if (opt[0] == 'S')
        {
            scanf("%d", &y);
            page[y] = cur;
        }
        else
        {
            scanf("%d", &z);
            cur = page[z];
        }
        printf("%d ", cur ? val[cur] : -1);
    }
    return 0;
}

标签:持久,浅谈,val,化栈,tot,fa,cur
From: https://www.cnblogs.com/CodingShark/p/17031388.html

相关文章

  • 浅谈西门子Teamcenter和MES的关系
    Teamcenter是西门子工业软件里的主打产品,主要用来实施企业产品设计数据管理、物料清单管理和工艺规划管理,也就是常说的PDM、BOM和TCM(或者CAPP)。而Teamcenter能够在行业占......
  • RabbitMQ 持久化 可靠性投递 可靠性消费(2)
    默认情况下,exchange、queue、message等数据都是存储在内存中的,这意味着如果RabbitMQ重启、关闭、宕机时所有的信息都将丢失。RabbitMQ提供了持久化来解决这个问题,持久......
  • Redis AOF持久化
    aof日志这种保存写操作命令到日志的持久化方式,就是Redis里的AOF(*AppendOnlyFile*)持久化功能,注意只会记录写操作命令,读操作命令是不会被记录的。在Redis中A......
  • 使用嵌套的ScriptableObject及ReorderableList创建习题持久化数据
    使用嵌套的ScriptableObject及ReorderableList创建习题持久化数据效果展示题集持久化数据:存储题目,可以直接在inspector面板上创建对应的问题子项问题持久化数据:源码......
  • 浅谈多项式与生成函数
    本文源码约34k,可能需要一段时间加载\(\LaTeX\)。首先需要注意的是,本文中将不会涉及具体的程式化求解,即与代码实现无关。同样的,阅读本文需要你掌握基础的快速傅里叶变换......
  • Unity3D之数据持久化储存
        首先我们来看两段Unity3D中实现数据读写的简单代码吧://保存数据PlayerPrefs.SetString("Name",mName);PlayerPrefs.SetInt("Age",mAge);PlayerPref......
  • 浅谈一下go语言中的slice及其一些小坑
    数组数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。虽然数组元素可以被修改,但是数组长度是固定的,而且在go语言中数组的长度也是数组类......
  • android基础02-广播、持久化、权限、ContentProvider
    广播Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应用程序的。......
  • 浅谈存储系统:LSM 树设计原理
    我在上篇文章ApachePulsar的架构设计中介绍了Pulsar存算分离的架构,其中broker只负责计算,由BookKeeper负责底层的存储,我还画了这样一张图说明BookKeeper读写分......
  • Sentinel-dashboard数据持久化到InfluxDB(四)
    之前的有做过sentinel整合的工作,已经完成sentinel客户端集成到普通微服务、集成到gateway,以及sentinel控制台的规则数据持久化到nacos,当时的工作基本做的差不多了,但是还差......