• 可持久化平衡树模板


    代码思想十分简单,不赘述。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    #define reg register
    inline int read() {
        int res = 0;char ch = getchar();bool fu = 0;
        while(!isdigit(ch)) fu |= (ch == '-'), ch = getchar();
        while(isdigit(ch)) res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar();
        return fu ? -res : res;
    }
    #define N 500005
    int n;
    int tot, rt[N];
    int val[N * 50], ch[N * 50][2], siz[N * 50], pri[N * 50];
    inline void update(int o) {
        siz[o] = siz[ch[o][0]] + siz[ch[o][1]] + 1;
    }
    inline int newnode(int v) {
        siz[++tot] = 1;
        val[tot] = v;
        pri[tot] = rand();
        return tot;
    }
    inline void cpyfrom(int x, int y) {
        siz[x] = siz[y], val[x] = val[y], ch[x][0] = ch[y][0], ch[x][1] = ch[y][1], pri[x] = pri[y];
    }
    int Merge(int x, int y) 
    {
        if (x * y == 0) return x + y;
        int jd = ++tot;
        if (pri[x] < pri[y]) {
            cpyfrom(jd, x);
            ch[jd][1] = Merge(ch[jd][1], y);
            update(jd);
            return jd;
        } else {
            cpyfrom(jd, y);
            ch[jd][0] = Merge(x, ch[jd][0]);
            update(jd);
            return jd;
        }
    }
    void Split(int o, int k, int &x, int &y) 
    {
        if (!o) {x = y = 0;return;}
        if (val[o] <= k) x = ++tot, cpyfrom(x, o), Split(ch[x][1], k, ch[x][1], y), update(x);
        else y = ++tot, cpyfrom(y, o), Split(ch[y][0], k, x, ch[y][0]), update(y);
    }
    inline void insert(int &root, int v) 
    {
        int a = 0, b = 0;
        Split(root, v, a, b);
        root = Merge(Merge(a, newnode(v)), b);
    }
    inline void delet(int &root, int v) 
    {
        int a = 0, b = 0, c = 0;
        Split(root, v, a, b);
        Split(a, v - 1, a, c);
        c = Merge(ch[c][0], ch[c][1]);
        root = Merge(Merge(a, c), b);
    }
    inline int rnk(int &root, int v)
    {
        int a = 0, b = 0;
        Split(root, v - 1, a, b);
        int res = siz[a];
        root = Merge(a, b);
        return res;
    }
    inline int kth(int o, int k)
    {
        while(1) {
            if (siz[ch[o][0]] >= k) o = ch[o][0];
            else if (k == siz[ch[o][0]] + 1) return o;
            else k -= siz[ch[o][0]] + 1, o = ch[o][1];
        }
    }
    
    inline int findpre(int &root, int v)
    {
        int a = 0, b = 0;
        Split(root, v - 1, a, b);
        int res = kth(a, siz[a]);
        root = Merge(a, b);
        return val[res];
    }
    inline int findnxt(int &root, int v) 
    {
        int a = 0, b = 0;
        Split(root, v, a, b);
        int res = kth(b, 1);
        root = Merge(a, b);
        return val[res];
    }
    
    signed main()
    {
        srand((unsigned)20020315);
        insert(rt[0], -2147483647), insert(rt[0], 2147483647);
        n = read();
        for (reg int i = 1 ; i <= n ; i ++)
        {
            int lst = read(), opt = read(), x = read();
            rt[i] = rt[lst];
            if (opt == 1) insert(rt[i], x);
            else if (opt == 2) delet(rt[i], x);
            else if (opt == 3) printf("%d
    ", rnk(rt[i], x));
            else if (opt == 4) printf("%d
    ", val[kth(rt[i], x + 1)]);
            else if (opt == 5) printf("%d
    ", findpre(rt[i], x));
            else printf("%d
    ", findnxt(rt[i], x));
        }
        return 0;
    }
  • 相关阅读:
    idea 使用
    scala
    Java开发工具
    ActiveMQ基础
    Java 多线程实战
    Java 内部类和Lambda
    Spring 学习
    平滑重启php
    opcache
    redis的hscan命令
  • 原文地址:https://www.cnblogs.com/BriMon/p/10389094.html
Copyright © 2020-2023  润新知