用 fhq_Treap 实现可持久化平衡树
支持对历史版本进行操作的平衡树
Treap 和 Splay 都是旋来旋去的
这样平衡树可持久化听起来不太好搞?
还有 fhq_Treap !
每次涉及操作就复制一个节点出来
操作历史版本就继承它的根继续往下搞
在 Split 和 Merge 里加上有关可持久化的操作即可
这里因为写了根据权值来分割的 Split
所以就写比较传统的 getrank 了 = =
所以其他的一些涉及 Split 的操作都改了改
其实还是挺好写的
终于还是写了传引用的 Split
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cctype> #include<cstdio> #include<cmath> #include<ctime> #define lson t[cur].ch[0] #define rson t[cur].ch[1] using namespace std; const int MAXN = 500001, inf = 0x7fffffff; struct Node{ int ch[2], siz, val, prio; Node(){ch[0] = ch[1] = siz = val = 0;} }t[MAXN * 50]; int Root[MAXN], n, poolcur; inline int rd() { register int x = 0; register char c = getchar(); register bool f = false; while(!isdigit(c)) { if(c == '-') f = true; c = getchar(); } while(isdigit(c)) { x = x * 10 + c - 48; c = getchar(); } return f ? -x : x; } inline int newnode(int val) { register int cur = ++poolcur; t[cur].siz = 1; t[cur].prio = rand(); t[cur].val = val; return cur; } inline void pushup(int cur) { t[cur].siz = t[lson].siz + t[rson].siz + 1; return; } void Split(int cur, int val, int &x, int &y) { if(!cur) x = y = 0; else { if(t[cur].val <= val) { x = ++poolcur; t[x] = t[cur]; Split(t[x].ch[1], val, t[x].ch[1], y); pushup(x); } else { y = ++poolcur; t[y] = t[cur]; Split(t[y].ch[0], val, x, t[y].ch[0]); pushup(y); } } return; } int Merge(int x, int y) { if(!x) return y; if(!y) return x; if(t[x].prio < t[y].prio) { int nw = ++poolcur; t[nw] = t[x]; t[x].ch[1] = Merge(t[x].ch[1], y); pushup(x); return x; } else { int nw = ++poolcur; t[nw] = t[y]; t[y].ch[0] = Merge(x, t[y].ch[0]); pushup(y); return y; } } void Insert(int &root, int val) { int x, y; Split(root, val, x, y); root = Merge(Merge(x, newnode(val)), y); return; } void Remove(int &root, int val) { int x, y, z; Split(root, val, x, z); Split(x, val - 1, x, y); y = Merge(t[y].ch[0], t[y].ch[1]); root = Merge(Merge(x, y), z); return; } int getrnk(int &root, int val) { int x, y; Split(root, val - 1, x, y); int ans = t[x].siz + 1; root = Merge(x, y); return ans; } int findkth(int cur, int k) { if(k <= t[lson].siz) return findkth(lson, k); if(k == t[lson].siz + 1) return t[cur].val; return findkth(rson, k - t[lson].siz - 1); } int getpre(int &root, int val) { int x, y; Split(root, val - 1, x, y); if(!x) return -inf; int k = t[x].siz; int ans = findkth(x, k); root = Merge(x, y); return ans; } int getnxt(int &root, int val) { int x, y; Split(root, val, x, y); if(!y) return inf; int ans = findkth(y, 1); root = Merge(x, y); return ans; } int main() { srand(time(NULL)); n = rd(); int ver, opt, x; for(int i = 1; i <= n; ++i) { ver = rd(); opt = rd(); x = rd(); Root[i] = Root[ver]; switch(opt) { case 1: Insert(Root[i], x); break; case 2: Remove(Root[i], x); break; case 3: printf("%d\n", getrnk(Root[i], x)); break; case 4: printf("%d\n", findkth(Root[i], x)); break; case 5: printf("%d\n", getpre(Root[i], x)); break; case 6: printf("%d\n", getnxt(Root[i], x)); break; } } return 0; }
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/