Splay模板
Posted zzh-brim
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Splay模板相关的知识,希望对你有一定的参考价值。
并没有写序列翻转的板子;
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 10000010 #define inf 0x7f7f7f7f struct SplayTree { int ch[2], fa; int val, siz; int cnt;// 副本数 }t[maxn]; int Root, tot; void pushup(int o) { t[o].siz = t[t[o].ch[0]].siz + t[t[o].ch[1]].siz + t[o].cnt; } void rotate(int x) { int y = t[x].fa, d = (t[y].ch[1] == x); t[ t[y].ch[d] = t[x].ch[d ^ 1] ].fa = y; // x 的儿子给 y ; t[ t[x].fa = t[y].fa ].ch[ t[t[y].fa].ch[1] == y ] = x; // x 归为 y 的父亲的儿子 ; t[ t[x].ch[d ^ 1] = y ].fa = x; // y 归为 x 的儿子; pushup(y), pushup(x); } void Splay(int x, int f) // 把 x 旋转成 f 的儿子, 如果 f = 0, x 旋转到根节点: { while(t[x].fa != f) { int y = t[x].fa, z = t[y].fa; if(z != f) { /* if ((t[z].ch[0] == y) == (t[y].ch[0] == x)) { rotate(y); } else { rotate(x); }*/ rotate( (t[z].ch[0] == y) == (t[y].ch[0] == x) ? y : x);// x 与 y 为同一边子树 旋转 y, 否则旋转 x; } rotate(x); } pushup(x); if(f == 0) Root = x; } void insert(int v) { int o = Root, u = 0; while(o && t[o].val != v) { u = o; int d = t[o].val < v; o = t[o].ch[d]; } if(o) { t[o].cnt ++; pushup(o); } else { o = ++tot; if (u) { int d = t[u].val < v; t[u].ch[d] = o; } t[o].fa = u; t[o].val = v;//cout<<t[o].val<<endl; t[o].siz = 1; t[o].cnt = 1; t[o].ch[1] = t[o].ch[0] = 0; } Splay(o, 0); } int K_th(int k) { int o = Root; if(t[o].siz < k) { return 0; } while(1) { if(k > t[t[o].ch[0]].siz + t[o].cnt) { k -= t[t[o].ch[0]].siz + t[o].cnt; o = t[o].ch[1]; } else if(t[t[o].ch[0]].siz >= k) { o = t[o].ch[0]; } else { break; } } Splay(o, 0); return t[o].val; } void Find(int x) { int o = Root; if(!o) return ; /* while(1) { if(t[o].val == x) { Splay(o, 0); return ; } int d = t[o].val < x; if(!t[o].ch[o]) return ; o = t[o].ch[o]; }*/ while(t[o].ch[t[o].val < x] and x != t[o].val) { o = t[o].ch[t[o].val < x]; } Splay(o, 0); } int Next(int x, int d) { Find(x); int o = Root; if( (t[o].val > x and d) or (t[o].val < x and !d)) return o; o = t[o].ch[d]; while(t[o].ch[d ^ 1]) o = t[o].ch[d ^ 1]; return o; } void Del(int x) { int lst = Next(x, 0); int nxt = Next(x, 1); Splay(lst, 0);Splay(nxt, lst); int del = t[nxt].ch[0]; if(t[del].cnt > 1) { t[del].cnt --; Splay(del, 0); } else t[nxt].ch[0] = 0; } int main() { insert(inf); insert(-inf); int n; cin >> n; while(n--) { int opt, x; scanf("%d%d", &opt, &x); if(opt == 1) { insert(x); } else if(opt == 2) { Del(x); } else if(opt == 3) { Find(x); printf("%d\n", t[t[Root].ch[0]].siz); } else if(opt == 4) { printf("%d\n", K_th(x + 1)); } else if(opt == 5) { printf("%d\n", t[Next(x, 0)].val); } else { printf("%d\n", t[Next(x, 1)].val); } } return 0; }
以上是关于Splay模板的主要内容,如果未能解决你的问题,请参考以下文章