简要题意

你需要维护一个栈,有 \(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. 二、Celery执行一步任务

    二.Celery执行异步任务 2.1.基本使用 创建项目celerypro 创建异步任务执行文件celery_task: import celery import time backend='redi ...

  2. Java多线程(6):锁与AQS(下)

    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 之前说过,AQS(抽象队列同步器)是Java锁机制的底层实现.既然它这么优秀,是骡子是马,就拉出来溜溜吧. 首先用重入锁来实现简单的累加,就像这 ...

  3. Rocky之Mysql-MHA高可用

    9.半同步复制 安装插件三种方法: 第一种: mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so' 安装 在 ...

  4. Windows 环境搭建 PostgreSQL 物理复制高可用架构数据库服务

    PostgreSQL 高可用数据库的常见搭建方式主要有两种,逻辑复制和物理复制,上周已经写过了关于在Windows环境搭建PostgreSQL逻辑复制的教程,这周来记录一下 物理复制的搭建方法. 首先 ...

  5. redis的缓存穿透、击穿、雪崩以及实用解决方案

    今天来聊聊redis的缓存穿透.击穿.雪崩以及解决方案,其中解决方案包括类似于布隆过滤器这种网上一搜一大片但是实际生产部署有一定复杂度的,也有基于spring注解通过一行代码就能解决的,其中各有优劣, ...

  6. 【笔记】CF1714F Build a Tree and That Is It 及相关

    题目传送门 细节较多的构造题. 解决思路 题目中虽然说是无根树,但我们可以钦定这棵树的根为 1,方便构造,这是不影响结果的. 以下记给定的三段长度为 \(a,b,c\) . 先考虑无解的情况. 首先, ...

  7. centos ssh 连接缓慢

    在连接apache,ssh,mysql等服务器时,如果出现连接过慢,可能的原因是dns 的反向查询.反向解析是防止假冒的IP连接服务器,把IP解析成域名,来提高安全性,看这个IP是否是伪造,这是dns ...

  8. zabbix6.0安装

    一.简述 zabbix6.0 对相关软件版本要求较高,需要php7.25以上php8.0以下版本支持,若使用mysql数据库,其最低要求为mysql8.0,本此搭建采用的是使用较广的lnmp架构 za ...

  9. vs2019中使用Git,新建项目时总提示部分项目位于解决方案文件夹外

    最终还是用Git工具传上去的. 小伙子,用Git Bush或者Git CMD 和Git GUI传吧 我是用Git GUI. Git GUI汉化.感谢大佬 https://blog.csdn.net/u ...

  10. oracle 内置函数(二)字符函数

    主要函数: 大小写转换函数 获取子字符串函数(字符串截取) 获取字符串长度函数 字符串连接函数 去除子字符串函数 字符替换函数 字符串出现次数 字符串按照特定符号拆分多行 一.大小写转换 1.uppe ...