可持久化数组模板

学会动态开点很重要。

本代码采用指针形式,点区间为左闭右开。

#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;

inline ll read()
{
    ll x = 0, f = 0;
    char ch = getchar();
    while (!isdigit(ch))
        f |= (ch == '-'), ch = getchar();
    while (isdigit(ch))
        x = (x << 1) + (x << 3) + (ch ^= 48), ch = getchar();
    return f ? -x : x;
}

const ll N = 1e6 + 3;
int n, m, tot, a[N];

struct node
{
    int L, R, w;
    node *lc, *rc;
};

struct node by[N * 21], *pool = by, *root[N];

node *New()
{
    return ++pool;
}

node *build(int l, int r)
{
    node *now = New();
    now->L = l;
    now->R = r;
    if (l + 1 < r)
    {
        ll mid = (now->L + now->R) >> 1;
        now->lc = build(l, mid);
        now->rc = build(mid, r);
    }
    else
    {
        now->w = a[l];
        now->lc = now->rc = NULL;
    }
    return now;
}

inline bool out(node *&now, int l, int r)
{
    return (now->R <= l) || (r < now->L);
}

void change(node *&pre, node *&now, int x, int w)
{
    *now = *pre;
    if (pre->L == x and pre->R == x + 1)
        now->w = w;
    else
    {
        if (!out(pre->lc, x, x + 1))
        {
            now->lc = New();
            change(pre->lc, now->lc, x, w);
        }
        else
        {
            now->rc = New();
            change(pre->rc, now->rc, x, w);
        }
    }
}

int check(node *now, int x)
{
    if (now->L == x && now->R == x + 1)
        return now->w;
    if (!out(now->lc, x, x + 1))
        return check(now->lc, x);
    else
        return check(now->rc, x);
}

int main()
{
    n = read(), m = read();
    for (int i = 1; i <= n; ++i)
    {
        a[i] = read();
    }
    root[0] = build(1, n + 1);
    for (int i = 0; i < m; ++i)
    {
        ll v = read(), opt = read(), x = read(), k;
        if (opt == 1)
        {
            k = read();
            root[++tot] = New();
            change(root[v], root[tot], x, k);
        }
        else
        {
            ll ans = check(root[v], x);
            printf("%lld
", ans);
            root[++tot] = New();
            root[tot] = root[v];
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/EdisonBa/p/14968239.html