• [Luogu 3919]【模板】可持久化数组(可持久化线段树/平衡树)


    Description

    如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作

    1. 在某个历史版本上修改某一个位置上的值

    2. 访问某个历史版本上的某一位置的值

    此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)

    Input

    输入的第一行包含两个正整数 N, M, 分别表示数组的长度和操作的个数。

    第二行包含N个整数,依次为初始状态下数组各位的值(依次为 a_i1iN)。

    接下来M行每行包含3或4个整数,代表两种操作之一(ii为基于的历史版本号):

    1. 对于操作1,格式为vi​​ 1 loci​​ valuei​​,即为在版本v_ivi​​的基础上,将 aloci​​​​ 修改为 valuei​​

    2. 对于操作2,格式为vi​​ 2 loci​​ ,即访问版本 vi​​ 中的 aloci​​​​ 的值

    Output

    输出包含若干行,依次为每个操作2的结果。

    Sample Input

    5 10
    59 46 14 87 41
    0 2 1
    0 1 1 14
    0 1 1 57
    0 1 1 88
    4 2 4
    0 2 5
    0 2 4
    4 2 1
    2 2 2
    1 1 5 91

    Sample Output

    59
    87
    41
    87
    88
    46

    HINT

    数据规模:

    对于30%的数据:1N,M103​​

    对于50%的数据:1N,M104​​

    对于70%的数据:1N,M105​​

    对于100%的数据:1N,M106​​,1loci​​N,0vi​​<i,109​​ai​​,valuei​​109​​

    经测试,正常常数的可持久化数组可以通过,请各位放心

    数据略微凶残,请注意常数不要过大

    另,此题I/O量较大,如果实在TLE请注意I/O优化

    样例说明:

    一共11个版本,编号从0-10,依次为:

    • 0 : 59 46 14 87 41

    • 1 : 59 46 14 87 41

    • 2 : 14 46 14 87 41

    • 3 : 57 46 14 87 41

    • 4 : 88 46 14 87 41

    • 5 : 88 46 14 87 41

    • 6 : 59 46 14 87 41

    • 7 : 59 46 14 87 41

    • 8 : 88 46 14 87 41

    • 9 : 14 46 14 87 41

    • 10 : 59 46 14 87 91

    题解

    $rt$,当模板存着...

     1 //It is made by Awson on 2017.10.3
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <string>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Max(a, b) ((a) > (b) ? (a) : (b))
    17 #define Min(a, b) ((a) < (b) ? (a) : (b))
    18 #define sqr(x) ((x)*(x))
    19 #define insert INSERT
    20 using namespace std;
    21 const int N = 1e6;
    22 void read(int &x) {
    23     char ch; bool flag = 0;
    24     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    25     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    26     x *= 1-2*flag;
    27 }
    28 
    29 struct node {
    30     int key;
    31     node *child[2];
    32 }sgm[N*20+5], *pos = sgm;
    33 node* root[N+5];
    34 int n, m, a[N+5];
    35 int opt, v, loc, val;
    36 
    37 void build(node *o, int l, int r) {
    38     if (l == r) {
    39         o->key = a[l];
    40         return;
    41     }
    42     int mid = (l+r)>>1;
    43     o->child[0] = ++pos; build(o->child[0], l, mid);
    44     o->child[1] = ++pos; build(o->child[1], mid+1, r);
    45 }
    46 void insert(node* &o, int l, int r, int loc, int val) {
    47     node* tmp = o;
    48     o = ++pos;
    49     if (l == r) {
    50         o->key = val;
    51         return;
    52     }else {
    53         o->child[0] = tmp->child[0];
    54         o->child[1] = tmp->child[1];
    55     }
    56     int mid = (l+r)>>1;
    57     if (loc <= mid) insert(o->child[0], l, mid, loc, val);
    58     else insert(o->child[1], mid+1, r, loc, val);
    59 }
    60 int query(node *o, int l, int r, int loc) {
    61     if (l == r) return o->key;
    62     int mid = (l+r)>>1;
    63     if (loc <= mid) return query(o->child[0], l, mid, loc);
    64     else return query(o->child[1], mid+1, r, loc);
    65 }
    66 void work() {
    67     read(n), read(m);
    68     for (int i = 1; i <= n; i++) read(a[i]);
    69     root[0] = pos;
    70     build(root[0], 1, n);
    71     for (int i = 1; i <= m; i++) {
    72         read(v), read(opt);
    73         if (opt == 1) {
    74             read(loc), read(val);
    75             root[i] = root[v];
    76             insert(root[i], 1, n, loc, val);
    77         }
    78         else {
    79             read(loc);
    80             root[i] = root[v];
    81             printf("%d
    ", query(root[i], 1, n, loc));
    82         }
    83     }
    84 }
    85 int main() {
    86     work();
    87     return 0;
    88 }
  • 相关阅读:
    JavaScript+IndexedDB实现留言板:客户端存储数据
    怎么限制Google自动调整字体大小
    《互联网时代》告诉我的互联网简史(二)
    《互联网时代》告诉我的互联网简史(一)
    CSS换行:word-wrap、word-break和text-wrap区别
    php中的字符串和正则表达式
    php数组使用小结
    问题:关于一个贴友的js留言板的实现
    问题:关于坛友的一个定时重复显示和隐藏div的实现
    使用union 外加count
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7623624.html
Copyright © 2020-2023  润新知