简要题意

你需要维护一个栈,有 \(n\) 个操作,支持:

  • 给定一个 \(x\),将 \(x\) 加入栈。
  • 将一个元素出栈。
  • 给定一个 \(x\),将当前栈回退到 第 \(x\) 操作前

每一次操作结束后,你需要输出栈顶元素。如果当前栈是一个空栈,那么输出 \(-1\)。

数据保证操作合法,且 \(1 \le n \le 8 \times 10^{4}\)。

思路

据说本题存在 \(O(n)\) 做法,但是我不会,这里有一个 \(O(n\log n)\) 做法。

对于 回退 之类的字眼,我们肯定会想到可持久化,由于栈一般时用数组实现的,所以我们可以写一个可持久化数组。如果不会可持久化数组,请去做 模板题

下面有一个用数组实现的栈的简要代码,对于分析很有帮助:

int stk[114514],t;
void push(int v){
stk[++t]=v;
}
void pop(){
t--;
}
int top(){
return (t==0)?(-1):(stk[t]);
}

我们可以考虑用可持久化数组来维护 stk,那么 \(t\) 怎么办?我们发现,\(t\) 需要是一个可持久化变量,可持久化变量不就是数组吗?于是我们直接使用数组 \(T_i\) 来表示第 \(i\) 次操作后栈顶指针 \(t\)。

整个代码时间复杂度和空间复杂度都是 \(O(n\log n)\) 的(可持久化的开销)。

代码

#include <bits/stdc++.h>
#define mid ((l+r)>>1)
using namespace std; const int SIZE = 8e4+5;
struct{
int l,r,v;
}t[SIZE*25];
int top;
int root[SIZE*25];
int n; int newnode(int i){
t[++top]=t[i];
return top;
} int update(int i,int l,int r,int p,int val){
i=newnode(i);
if(l==r){
t[i].v=val;
return i;
}
if(p<=mid){
t[i].l=update(t[i].l,l,mid,p,val);
}
else{
t[i].r=update(t[i].r,mid+1,r,p,val);
}
return i;
} int query(int i,int l,int r,int p){
if(l==r){
return t[i].v;
}
if(p<=mid){
return query(t[i].l,l,mid,p);
}
else{
return query(t[i].r,mid+1,r,p);
}
} int stop[SIZE]; int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
root[i]=root[i-1];
stop[i]=stop[i-1];
char op;
int x;
cin>>op;
if(op=='a'){
cin>>x;
root[i]=update(root[i-1],1,n,(++stop[i]),x);
}
else if(op=='s'){
stop[i]--;
}
else{
cin>>x;
root[i]=root[x-1];
stop[i]=stop[x-1];
}
if(stop[i]!=0){
cout<<query(root[i],1,n,stop[i])<<'\n';
}
else{
cout<<-1<<'\n';
}
}
return 0;
}

跑了 \(113\) 毫秒,比 \(O(n)\) 的慢。

AC Record

可持久化栈学习笔记 | 题解 P6182 [USACO10OPEN]Time Travel S的更多相关文章

  1. 可持久化trie学习笔记

    其实很早之前就想学习可持久化trie,不过由于换队友等情况,还是优先去学数论和计算几何,今天突然心血来潮学了一发可持久化trie,感觉还是蛮简单的,不过由于自己很长时间没写过可持久化了,都快忘了是个什 ...

  2. PHP全栈学习笔记18

    php基础知识,JavaScript,jQuery,ajax基础知识 linux基础知识,mysql数据库的基础与优化 程序设计,PHP框架基础知识,算法,逻辑思维,高并发 PHP基础知识 引用变量, ...

  3. PHP全栈学习笔记13

    php与ajax技术 web2.0的到来,ajax逐渐成为主流,什么是ajax,ajax的开发模式,优点,使用技术.(ajax概述,ajax使用的技术,需要注意的 问题,在PHP应用ajax技术的应用 ...

  4. PHP全栈学习笔记12

    php简介,php历史,php后端工程师职业前景,php技术方向,php后端工程师职业体系介绍. php是世界上使用最广泛的web开发语言,是超文本预处理器,是一种通用的开源脚本语言,语法吸收了c语言 ...

  5. PHP全栈学习笔记17

    phpmyadmin教程 管理页进入phpmyadmin 打开C:\wamp\apps\phpmyadmin3.5.1下的配置文件:config.inc 修改密码 创建与修改数据库.数据表 字段类型 ...

  6. PHP全栈学习笔记16

    <?php $fileName = "php大师.test.php"; //补充程序,显示文件名(不包括扩展名) $start = strrpos($fileName, &q ...

  7. PHP全栈学习笔记15

    PHP标记风格 PHP一共支持4种标记风格 <?php echo "这是XML风格的标记"; ?> 脚本风格 <script language="php ...

  8. PHP全栈学习笔记14

    一.搭建PHP开发环境 Apahce服务器 Dreamwear创建站点 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitiona ...

  9. PHP全栈学习笔记11

    连接MySQL mysql_connect(servername,username,password); 面向对象: <?php $servername = "localhost&qu ...

  10. PHP全栈学习笔记10

    php常量,常量是不能被改变的,由英文字母,下划线,和数字组成,但是数字不能作为首字母出现. bool define ( string $name , mixed $value [, bool $ca ...

随机推荐

  1. Python学习笔记----操作字符串

    1.字符串相加.列表相加.列表和字符串不能混着使用 #序列相加 a="hello" b="python" c=a+b print("字符串相加的结果& ...

  2. ansible使用临时命令通过模块来执行任务

    使用临时命令通过模块来执行任务 一.查看系统上安装的所有模块 ansible-doc -l 查看ping模块帮助文档 ansible-doc ping 1.ansible模块 文件模块: copy:将 ...

  3. JAVA系列之JVM内存调优

    一.前提 JVM性能调优牵扯到各方面的取舍与平衡,往往是牵一发而动全身,需要全盘考虑各方面的影响.在优化时候,切勿凭感觉或经验主义进行调整,而是需要通过系统运行的客观数据指标,不断找到最优解.同时,在 ...

  4. Blog1:nchu-software-oop-2022-1~3

    (1) 前言 针对在完成三次作业过程中产生的问题进行总结与分析. 三次作业一共十五(9+3+3)道题目,其中前两次难度较为简单,第三次复杂程度飞跃式上涨. 其中,涉及到java语言中基本的输入输出语句 ...

  5. 我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang

    第四期 · 将部分数据存储至Mysql,使用axios通过golang搭建的http服务器获取数据. 新建数据库 DROP DATABASE VUE; create database if not e ...

  6. 陪你去看 Lodash.js 起步

    lodash 起步(数组) Lodash 是一个较为流行的 JavaScript 的实用工具库. 在开发过程中如果能熟练使用一些工具库提供的方法,有利于提高开发效率. 笔者从 API 上入手,不分析其 ...

  7. 什么是 X.509 证书以及它是如何工作的?

    X.509 证书是基于广泛接受的国际电信联盟 (ITU) X.509 标准的数字证书,该标准定义了公钥基础设施 (PKI) 证书的格式. 它们用于管理互联网通信和计算机网络中的身份和安全. 它们不显眼 ...

  8. C#面试题基础

    1.什么是GAC,他的作用是什么? 我的这篇文章有详细的介绍 https://www.cnblogs.com/zxtang/p/14313273.html 2.描述一个被protected inter ...

  9. python——os模块学习

    import os #1.获取当前使用的操作系统 #返回操作系统类型,nt是windows,posix是linux print(os.name) #print是一个函数,函数里面进行条件判断'posi ...

  10. 2018 Web开发人员学习路线图

    以下 Web 开发人员学习路线图是来自 Github developer-roadmap 项目,目前已经有繁体版翻译 developer-roadmap-chinese. 主要有三个方向,分别为前端开 ...