abc 273 e 题解
abc 273 e
题意
给定一个笔记本和一个整数序列 \(A\),有四种询问:
-
ADD x
:在 \(A\) 的末尾添加 \(x\)。 -
DELETE
:删除 \(A\) 的末尾元素。 -
SAVE y
:将当前序列替换掉笔记本第 \(y\) 页的序列。 -
LOAD z
:将序列 \(A\) 替换成笔记本第 \(z\) 页的序列。
最开始 \(A\) 是空的,笔记本的每一页也是空的,请你输出每次询问后 \(A\) 的末尾元素。
思路
其实我们可以将这个在序列上的四种操作看做成在树上做操作。
所以,令当前序列 \(A\) 的最后一个元素为 \(now\),并且已经操作了 \(i\) 次,那么,四种操作可以分别转化为:
-
ADD x
:让 \(now\) 多一个儿子 \(i + 1\),并将 \(x\) 标记在 \(i + 1\) 上。 -
DELETE
:将 \(now\) 变成 \(now\) 的父亲。 -
SAVE y
:将第 \(y\) 页的元素替换成 \(now\),这样就还是可以访问 \(now\) 前面的所有元素。 -
LOAD z
:将 \(now\) 替换成记录在第 \(z\) 页的元素。
每次输出标记在 \(now\) 上的元素即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int q, x, now, n, a[N], fa[N];
string op;
map<int, int> p; // 记录每一页所对应的最后一个元素
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> q;
while (q--) {
cin >> op;
if (op == "ADD") {
int x;
cin >> x, a[++n] = x, fa[n] = now, now = n;
} else if (op == "DELETE") {
now = fa[now];
} else if (op == "SAVE") {
int y;
cin >> y, p[y] = now;
} else {
int z;
cin >> z, now = p[z];
}
cout << (!now ? -1 : a[now]) << ' ';
}
return 0;
}