题目链接:【模板】可持久化线段树 1(可持久化数组) - 洛谷
题目描述:
输入描述:
输出描述:
样例:
说明:
这就是主席树的模板题
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl "\n"
#define N 1000005
struct node{
int ltree, rtree; //左右儿子的编号
int val;
}tree[N * 40];
int a[N]; //存输入
int arr[N]; //存每个版本的根节点编号
int cnt = 0; //每个节点的编号
int build(int rt, int l, int r){
tree[++cnt] = tree[rt];
rt = cnt;
if(l == r){
tree[rt].val = a[l];
return rt;
}
int mid = (l + r) / 2;
tree[rt].ltree = build(rt, l, mid);
tree[rt].rtree = build(rt, mid + 1, r);
return rt;
}
int updata(int rt, int l, int r, int L, int k){
tree[++cnt] = tree[rt];
rt = cnt;
if(l == r){
tree[rt].val = k;
return rt;
}
int mid = (l + r) / 2;
if(L <= mid){
tree[rt].ltree = updata(tree[rt].ltree, l, mid, L, k);
}else{
tree[rt].rtree = updata(tree[rt].rtree, mid + 1, r, L, k);
}
return rt;
}
ll query(int rt, int l, int r, int L){
if(l == r){
return tree[rt].val;
}
int mid = (l + r) / 2;
if(L <= mid){
return query(tree[rt].ltree, l, mid, L); //基于左儿子进行更改
}else{
return query(tree[rt].rtree, mid + 1, r, L); //基于右儿子进行更改
}
}
int main(){
ios::sync_with_stdio(false);
int n, m;
cnt = 0;
while(cin >> n >> m){
for(int i = 1; i <= n; i++){
cin >> a[i];
}
arr[0] = build(cnt, 1, n);
for(int i = 1; i <= m; i++){
int v, aa, c;
ll va;
cin >> v >> aa;
if(aa == 1){
cin >> c >> va;
arr[i] = updata(arr[v], 1, n, c, va);
}else{
cin >> c;
cout << query(arr[v], 1, n, c) << endl;
tree[++cnt] = tree[arr[v]];
arr[i] = cnt;
}
}
}
return 0;
}