P3919 【模板】可持久化数组(可持久化线段树/平衡树)

题目: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值