题目链接:传送门
支持三种操作
1.T x:在文章末尾打下一个小写字母x
2.U x:撤销最后的x次修改操作
3.Q x:询问当前文章中第x个字母并输出
一眼主席树
比较板子
就没了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define A 1000010
#define B 2010
using namespace std;
typedef long long ll;
struct node {
int l, r, w; char c;
}tree[A << 4];
int n, m, rt[A], cnt, len;
void insert(int &k, int last, int l, int r, int pos, char c) {
k = ++cnt; tree[k] = tree[last];
if (l == r) {
tree[k].w = 1;
tree[k].c = c;
return;
}
int m = (l + r) >> 1;
if (pos <= m) insert(tree[k].l, tree[last].l, l, m, pos, c);
else insert(tree[k].r, tree[last].r, m + 1, r, pos, c);
tree[k].w = tree[tree[k].l].w + tree[tree[k].r].w;
}
char ask(int k, int l, int r, int pos) {
if (l == r) return tree[k].c;
int m = (l + r) >> 1;
if (pos <= tree[tree[k].l].w) return ask(tree[k].l, l, m, pos);
else return ask(tree[k].r, m + 1, r, pos - tree[tree[k].l].w);
}
int main(int argc, char const *argv[]) {
cin >> n;
while (n--) {
char opt; cin >> opt;
if (opt == 'T') {
char a; cin >> a; len++;
insert(rt[len], rt[len - 1], 1, 1e6, len, a);
}
else if (opt == 'U') {
int a; cin >> a; len++;
rt[len] = rt[len - a - 1];
}
else if (opt == 'Q') {
int a; cin >> a;
cout << ask(rt[len], 1, 1e6, a) << endl;
}
}
}