简要题意

你需要维护一个栈,有 \(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

最新文章

  1. PowerDesigner 逆向工程 Mariadb 失败
  2. 关于JSP---三大指令
  3. kenrnel 驱动中常用的宏
  4. java关于StringBuffer和StringBuilder写入文件的效率问题
  5. openwrt: Makefile 框架分析
  6. UIImagePicker照片选择器
  7. UVa572 Oil Deposits DFS求连通块
  8. asp.net 后台使用js弹窗失效问题
  9. 分布式文件系统MooseFS安装步骤
  10. openCV中cvSnakeImage()函数代码分析
  11. HDU 1863 畅通project (最小生成树是否存在)
  12. HDU1698_Just a Hook(线段树/成段更新)
  13. Arch安装KDE5
  14. 使用PhotoShop
  15. Nimbus&lt;一&gt;Storm系列(五)架构分析之Nimbus启动过程
  16. 会话技术cookie和session详解
  17. ionic ios项目真机运行-不用开发者账号
  18. 第四次作业之jieba库的应用
  19. bootstrap4 Reboot details summary 美化(点选禁止选中文本,单行隐藏角标,多行后移)
  20. 设计模式C++学习笔记之十二(Command命令模式)

热门文章

  1. Vue3 SFC 和 TSX 方式调用子组件中的函数
  2. 后端框架学习3------SpringMVC
  3. HTML基础知识(1)常用标签的使用 h、p、img、meta、a、iframe...
  4. 【多服务场景化解决方案】AR虚拟技术助力智能家装
  5. Debian玩红警2
  6. 加速乐逆向 cookies 参数
  7. 论文笔记 - An Explanation of In-context Learning as Implicit Bayesian Inference
  8. yaml使用
  9. 网络协议之:redis protocol 详解
  10. 基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换