题目:https://www.luogu.org/problem/P3919
维护这样的一个长度为 N 的数组,支持如下几种操作
在某个历史版本上修改某一个位置上的值
访问某个历史版本上的某一位置的值
此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)
1≤N,M≤ 1 0 6 10^6 106
code:
#include<bits/stdc++.h>
using namespace std;
#define mid ((l + r) >> 1)
#define Lson l, mid
#define Rson mid + 1, r
const int MAXN = 1e6 + 9;
int n, m, k;
int root[MAXN];
struct Tree
{
int l, r, num;
}tree[MAXN * 32];
int build(int l, int r)
{
int now = ++k;
if(l == r)
{
scanf("%d", &tree[now].num);
return now;
}
tree[now].l = build(Lson);
tree[now].r = build(Rson);
return now;
}
int upDate(int pre, int l, int r, int pos, int val)
{
int now = ++k;
if(l == r)
{
tree[now].num = val;
return now;
}
tree[now].l = tree[pre].l;
tree[now].r = tree[pre].r;
if(l < r)
{
if(pos <= mid)
tree[now].l = upDate(tree[pre].l, Lson, pos, val);
else
tree[now].r = upDate(tree[pre].r, Rson, pos, val);
}
return now;
}
int query(int pre, int l, int r, int pos)
{
int now = pre;
if(l == r)
{
return tree[now].num;
}
if(pos <= mid)
return query(tree[now].l, Lson, pos);
else
return query(tree[now].r, Rson, pos);
}
int main()
{
scanf("%d %d", &n, &m);
root[0] = build(1, n);
int vir, op, pos, val;
for(int i = 1; i <= m; i++)
{
scanf("%d %d %d", &vir, &op, &pos);
if(op == 1)
{
scanf("%d", &val);
root[i] = upDate(root[vir], 1, n, pos, val);
}
else
{
root[i] = root[vir];
printf("%d\n",query(root[vir], 1, n, pos));
}
}
return 0;
}