# 线段树学习笔记 下

5 篇文章 0 订阅
4 篇文章 0 订阅

## 可持久化线段树

### Solution

#### Code

#include <bits/stdc++.h>

using namespace std;

int n, m, a[26000001];
struct node{
int l, r, lp, rp, val;
} tree[26000001];
int cnt = 0, tot = 0, ver[26000001];

void save_ver(int rt){
ver[++tot] = rt;
}
int get_ver(int x){
return ver[x];
}

int build(int l, int r){
int ind = cnt; cnt++;
tree[ind].l = l, tree[ind].r = r;
if(l == r){
tree[ind].val = a[l];
return ind;
}
int mid = (l + r) >> 1;
tree[ind].lp = build(l, mid);
tree[ind].rp = build(mid + 1, r);
return ind;
}
int mod(int x, int y, int k){
int ind = cnt; cnt++;
tree[ind].l = tree[x].l, tree[ind].r = tree[x].r;
if(tree[ind].l == tree[ind].r){
tree[ind].val = k;
return ind;
}
int mid = (tree[ind].l + tree[ind].r) >> 1;
tree[ind].lp = tree[x].lp, tree[ind].rp = tree[x].rp;
if(y <= mid)
tree[ind].lp = mod(tree[x].lp, y, k);
else
tree[ind].rp = mod(tree[x].rp, y, k);
return ind;
}
int query(int x, int y){
if(tree[x].l == tree[x].r)
return tree[x].val;
int mid = (tree[x].l + tree[x].r) >> 1;
if(y <= mid)
return query(tree[x].lp, y);
else
return query(tree[x].rp, y);
}
double solve(int testcase, ...){

double used_time = clock();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", a + i);
}
ver[0] = build(1, n);
for(int i = 1; i <= m; i++){
int v, op, x, y;
scanf("%d%d%d", &v, &op, &x);
if(op == 1){
scanf("%d", &y);
save_ver(mod(get_ver(v), x, y));
}
else{
int curr = query(get_ver(v), x);
printf("%d\n", curr);
save_ver(mod(get_ver(v), x, curr));
}
}

return clock() - used_time;
}

signed main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);

#ifndef ONLINE_JUDGE
printf("Solved, used time %.0lfms.\n", solve(1, "local"));
#else
solve(1, ONLINE_JUDGE);
#endif
return 0;
}


• 7
点赞
• 7
收藏
觉得还不错? 一键收藏
• 0
评论
04-18 129
07-05 106
03-06 274
12-25
12-25
10-22
10-01
04-20 671
04-17 1194
04-16 1102
04-20 387
04-18 918
04-15 967
10-06

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。