Balanced trees and their persistence

It may have been affected by a pointer version of the treap before, and the treap has been written in pair format.
It turns out that quoting & is so convenient.
The code for this article is some very elegant writing I found.

void split(int i,int x,int &a,int &b)
{
    if(!i) a=0,b=0;
    else {
        if(w[i]<=x) a=i,split(t[i].r,x,t[i].r,b);
        else b=i,split(t[i].l,x,a,t[i].l);
        update(i);
    }
}

Then we can easily perform path copy when we persist the balanced tree.
Remember one thing, whoever changes it will copy whoever. (It can be understood as appearing with update)

int merge(int a,int b) //此Treap是按大根堆去维护
{
    if(!a||!b)return a+b; //这个好帅
    if(t[a].rnd>t[b].rnd)
    {
        int p=++cnt;t[p]=t[a]; //path copy
        t[p].r=merge(t[p].r,b); //普通的treap是把所有p变成a或b的,这里可以体现出来持久化
        update(p);return p;
    }
    else
    {
        int p=++cnt;t[p]=t[b];
        t[p].l=merge(a,t[p].l);
        update(p);return p;
    }
}
void split(int now,int k,int &x,int &y) //这里的k是一个权值,表示把原平衡树分为小于等于k,和大于k的两部分
{
    if(!now)x=y=0;
    else
    {
        if(t[now].v<=k)
        {
            x=++cnt;t[x]=t[now];
            split(t[x].r,k,t[x].r,y);
            update(x);
        }
        else 
        {
            y=++cnt;t[y]=t[now];
            split(t[y].l,k,x,t[y].l);
            update(y);
        }
    }
}

Attach an ugly LG3835 code written by myself:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#define N 500010
using namespace std;
inline char gc() {
    static char now[1<<16], *S, *T;
    if(S == T) {T = (S = now) + fread(now, 1, 1<<16, stdin); if(S == T) return EOF;}
    return *S++;
}
inline int read() {
    int x = 0, f = 1; char c = gc();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - 48; c = gc();}
    return x * f;
}
vector<int> pos;
struct treap {int l, r, sz, w, h;}t[N*50];
int root[N], len = 0, n;
inline int newnode(int x) {int ret; if(pos.size()) ret = pos.back(), pos.pop_back(); else ret = ++len; t[ret].l = 0; t[ret].r = 0; t[ret].sz = 1; t[ret].h = rand(); t[ret].w = x; return ret;}
inline void update(int p) {t[p].sz = t[t[p].l].sz + 1 + t[t[p].r].sz;}
int merge1(int i, int j) {
    if(!i || !j) return i + j;
    if(t[i].h < t[j].h) {
        int p = newnode(0); t[p] = t[i];
        t[p].r = merge1(t[p].r, j);
        update(p); return p;
    }else {
        int p = newnode(0); t[p] = t[j];
        t[p].l = merge1(i, t[p].l);
        update(p); return p;
    }
}
void split1(int p, int x, int &a, int &b) {//first: '<=' second: '>'
    if(!p) a = b = 0;
    else {
        if(t[p].w <= x) {
            a = newnode(0); t[a] = t[p];
            split1(t[a].r, x, t[a].r, b);
            update(a);
        }else {
            b = newnode(0); t[b] = t[p];
            split1(t[b].l, x, a, t[b].l);
            update(b);
        }
    }
}
void split2(int p, int k, int &a, int &b) {
    if(!p) a = b = 0;
    else {
        if(t[t[p].l].sz >= k) {
            b = newnode(0); t[b] = t[p];
            split2(t[b].l, k, a, t[b].l);
            update(b);
        }else {
            a = newnode(0); t[a] = t[p];
            split2(t[a].r, k - 1 - t[t[p].l].sz, t[a].r, b);
        }
    }
}
inline void insert1(int p, int x) {
    int a, b; split1(root[p], x, a, b);
    int nx = newnode(x);
    root[p] = merge1(a, merge1(nx, b));
}
inline void delete2(int p, int x) {
    int a, b, c, d;
    split1(root[p], x - 1, a, b);
    split2(b, 1, c, d);
    if(t[c].w == x) {
        pos.push_back(c);
        root[p] = merge1(a, d);
    }else root[p] = merge1(a, merge1(c, d));
}
inline int getrank(int p, int x) {
    int a, b;
    split1(root[p], x - 1, a, b);
    int ret = t[a].sz + 1;
    root[p] = merge1(a, b);
    return ret;
}
inline int getsa(int p, int k) {
    int a, b, c, d;
    split2(root[p], k - 1, a, b);
    split2(b, 1, c, d);
    int ret = t[c].w;
    root[p] = merge1(a, merge1(c, d));
    return ret;
}
inline int pre(int p, int x) {
    int a, b, c, d;
    split1(root[p], x - 1, a, b);
    split2(a, t[a].sz - 1, c, d);
    int ret = -0x7fffffff;
    if(d) ret = t[d].w;
    root[p] = merge1(c, merge1(d, b));
    return ret;
}
inline int nxt(int p, int x) {
    int a, b, c, d;
    split1(root[p], x, a, b);
    split2(b, 1, c, d);
    int ret = 0x7fffffff;
    if(c) ret = t[c].w;
    root[p] = merge1(a, merge1(c, d));
    return ret;
}
int main() {
    srand(20011118);
    n = read();
    for(int i = 1; i <= n; ++i) {
        int tim = read(), opt = read(), x = read();
        root[i] = root[tim];
        if(opt == 1) insert1(i, x);
        if(opt == 2) delete2(i, x);
        if(opt == 3) printf("%d\n", getrank(i, x));
        if(opt == 4) printf("%d\n", getsa(i, x));
        if(opt == 5) printf("%d\n", pre(i, x));
        if(opt == 6) printf("%d\n", nxt(i, x));
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325732390&siteId=291194637