zoukankan      html  css  js  c++  java
  • 可持久化树模板

    您需要维护一个序列,其中需要提供以下操作:

    1. 插入一个数到序列的第 t 版本使其成为序列的第 k 项,这个数为 x ;

    2. 删除序列的第 t 版本的第 k 项;

    3. 查询序列的第 t 版本的第 k 项。

    第 0 个版本为空序列。修改操作不会影响被修改的版本,而总是产生一个新版本。

    Input

    第一行有一个正整数 n 表示操作的数量。

    接下来 n 行每行第一个正整数 opt 表示操作的类型,后面有 3 个整数 t,k,x 或 2 个整数 t,k 表示操作的参数。

    1 ≤ n ≤ 3×105 , 1 ≤ opt ≤ 3  ,  0 ≤ x < 109 ,保证所有操作合法。

    由于数据量较大,可能需要使用特别的读入方式。

    Output

    对于每个查询操作输出一行一个数,表示查询的结果。

    Sample Input

    17
    1 0 1 1
    1 1 1 2
    1 2 1 3
    2 3 2
    3 4 2
    1 4 3 4
    1 5 1 5
    3 3 2
    1 3 4 6
    1 6 3 7
    1 7 1 8
    3 8 2
    3 7 3
    2 8 4
    2 9 2
    3 11 4
    3 10 4

    Sample Output

    1
    2
    3
    1
    6
    4

    Hint

    每次操作后的序列如下

    1 | 1
    2 | 2 1
    3 | 3 2 1
    4 | 3 1
    (=> 1)
    5 | 3 1 4
    6 | 5 3 1 4
    (=> 2)
    7 | 3 2 1 6
    8 | 5 3 7 1 4
    9 | 8 3 2 1 6
    (=> 3)
    (=> 1)
    10 | 5 3 7 4
    11 | 8 2 1 6
    (=> 6)
    (=> 4)

     
    //Splay Tree
    #include<bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    
    #define scl(i) scanf("%lld", &i)
    #define scll(i, j) scanf("%lld %lld", &i, &j)
    #define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k)
    #define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l)
    
    #define scs(i) scanf("%s", i)
    #define sci(i) scanf("%d", &i)
    #define scd(i) scanf("%lf", &i)
    #define scIl(i) scanf("%I64d", &i)
    #define scii(i, j) scanf("%d %d", &i, &j)
    #define scdd(i, j) scanf("%lf %lf", &i, &j)
    #define scIll(i, j) scanf("%I64d %I64d", &i, &j)
    #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
    #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
    #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)
    #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l)
    #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l)
    #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    #define lowbit(i) (i & (-i))
    #define mem(i, j) memset(i, j, sizeof(i))
    
    #define fir first
    #define sec second
    #define VI vector<int>
    #define ins(i) insert(i)
    #define pb(i) push_back(i)
    #define pii pair<int, int>
    #define VL vector<long long>
    #define mk(i, j) make_pair(i, j)
    #define all(i) i.begin(), i.end()
    #define pll pair<long long, long long>
    
    #define _TIME 0
    #define _INPUT 0
    #define _OUTPUT 0
    clock_t START, END;
    void __stTIME();
    void __enTIME();
    void __IOPUT();
    using namespace std;
    
    /*
    rope
    rope(rope&); //构造函数、传入rope可以用来拷贝
    push_back(x); // 在末尾添加x
    insert(pos, x); // 在pos插入x
    erase(pos, x); // 从pos开始删除x个
    copy(pos, len, x); // 从pos开始到pos+len为止用x代替
    replace(pos, x); // 从pos开始换成x
    substr(pos, x); // 提取pos开始x个
    at(x) / [x]; // 访问第x个元素
    时间复杂度为n*(n^0.5)
    */
    
    #include <ext/rope>
    using namespace __gnu_cxx;
    const int maxn = 3e5 + 10;
    
    int n, id;
    rope<int> * Rope[maxn];
    
    int main(void){__stTIME();__IOPUT();
    
        int n;
        sci(n);
    
        Rope[0] = new rope<int>();
    
        while(n--){
            int op, t, k, x;
            sciii(op, t, k);
            if(op == 1){
                sci(x);
                Rope[++id] = new rope<int>(*Rope[t]);
                Rope[id]->insert(k - 1, x);
            }
            if(op == 2){
                Rope[++id] = new rope<int>(*Rope[t]);
                Rope[id]->erase(k - 1, 1);
            }
            if(op == 3) printf("%d
    ", Rope[t]->at(k-1));
        }
    
    
    
    __enTIME();return 0;}
    
    
    void __stTIME()
    {
        #if _TIME
            START = clock();
        #endif
    }
    
    void __enTIME()
    {
        #if _TIME
            END = clock();
            cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;
        #endif
    }
    
    void __IOPUT()
    {
        #if _INPUT
            freopen("in.txt", "r", stdin);
        #endif
        #if _OUTPUT
            freopen("out.txt", "w", stdout);
        #endif
    }
    View Code
  • 相关阅读:
    深入理解Java:注解(Annotation)自定义注解入门
    Java基础之理解Annotation
    junit常用注解详细说明
    能判断是电脑端还是手机端的javascript
    Ext.js多文件选择上传,
    StringBuffer类和String类(原文地址 : http://www.cnblogs.com/springcsc/archive/2009/12/03/1616330.html)
    FileItem类的常用方法(关于文件上传的)
    js保留小数点后面几位的方法
    如何将div中的内容设置为空同时还要保留div本身
    使用html中的<input>标签上传多个文件(转)
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9756113.html
Copyright © 2011-2022 走看看