• 可持久化数组模板


    学会动态开点很重要。

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

    #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;
    }
    
  • 相关阅读:
    函数的嵌套
    函数对象
    命名关键字参数
    函数part4——函数的参数
    函数part3——函数的返回值
    函数part1——函数的使用原则
    flashback database 基本介绍一
    flash recovery area配置
    根据关键词获取进程ID然后杀掉进程
    rman的conver方法拷贝ASM文件
  • 原文地址:https://www.cnblogs.com/EdisonBa/p/14968239.html
Copyright © 2020-2023  润新知