码迷,mamicode.com
首页 > 其他好文 > 详细

可持久化平衡树

时间:2019-02-16 20:45:13      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:family   com   font   using   clu   split   else   sans   平衡树   

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

#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\n", rnk(rt[i], x));
        else if (opt == 4) printf("%d\n", val[kth(rt[i], x + 1)]);
        else if (opt == 5) printf("%d\n", findpre(rt[i], x));
        else printf("%d\n", findnxt(rt[i], x));
    }
    return 0;
}

 

可持久化平衡树

标签:family   com   font   using   clu   split   else   sans   平衡树   

原文地址:https://www.cnblogs.com/BriMon/p/10389094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!