_bzoj3224 Tyvj 1728 普通平衡树【Splay】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
保存splay模版
一刻不停写了一个小时多一点,幸好一遍过了!(其实带着freopen wa了一次)
添加一个易出bug的地方叭(鉴于曾经有次这么错过):此题平衡树里可以用重复值,我是用tm保存出现的次数,因此在求第k大时,千万小心循环结束条件!
#include <cstdio> #include <algorithm> const int maxn = 200005; int fa[maxn], ch[maxn][2], key[maxn], tm[maxn], siz[maxn], root, cnt, t1, t2; inline void pushup(int x) { siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + tm[x]; } inline void rotate(int x) { int y = fa[x]; if (y == ch[fa[y]][0]) { ch[fa[y]][0] = x; } else { ch[fa[y]][1] = x; } fa[x] = fa[y]; int dir = x == ch[y][1]; ch[y][dir] = ch[x][dir ^ 1]; fa[ch[x][dir ^ 1]] = y; ch[x][dir ^ 1] = y; fa[y] = x; pushup(y); pushup(x); } inline void splay(int x) { int p, flag1, flag2; while (fa[x]) { p = fa[x]; if (!fa[p]) { rotate(x); } else { flag1 = x == ch[p][1]; flag2 = p == ch[fa[p]][1]; if (flag1 ^ flag2) { rotate(x); } else { rotate(p); } rotate(x); } } root = x; } bool ist(int x, int val, int p, int dir) { if (!x) { key[++cnt] = val; tm[cnt] = 1; siz[cnt] = 1; fa[cnt] = p; ch[p][dir] = cnt; return true; } if (val < key[x]) { bool rt = ist(ch[x][0], val, x, 0); pushup(x); return rt; } else if (val > key[x]) { bool rt = ist(ch[x][1], val, x, 1); pushup(x); return rt; } else { ++tm[x]; ++siz[x]; return false; } } inline int fndmin(int x) { int rt = x, mn = key[x]; for (int i = ch[x][0]; i; i = ch[i][0]) { if (mn > key[i]) { mn = key[rt = i]; } } return rt; } inline int fndmax(int x) { int rt = x, mx = key[x]; for (int i = ch[x][1]; i; i = ch[i][1]) { if (mx < key[i]) { mx = key[rt = i]; } } return rt; } void del(int x, int value) { if (!x) { return; } if (value < key[x]) { del(ch[x][0], value); pushup(x); } else if (value > key[x]) { del(ch[x][1], value); pushup(x); } else if (tm[x] > 1) { --tm[x]; --siz[x]; } else { splay(x); fa[ch[x][0]] = fa[ch[x][1]] = 0; if (!ch[x][0]) { root = ch[x][1]; } else if (!ch[x][1]) { root = ch[x][0]; } else { root = fndmax(ch[x][0]); splay(root); fa[ch[x][1]] = root; ch[root][1] = ch[x][1]; pushup(root); } } } inline int qianqu(int val) { if (ist(root, val, 0, 0)) { splay(cnt); } int x = root; while (val != key[x]) { x = ch[x][val > key[x]]; } splay(x); x = key[fndmax(ch[x][0])]; del(root, val); return x; } inline int houji(int val) { if (ist(root, val, 0, 0)) { splay(cnt); } int x = root; while (val != key[x]) { x = ch[x][val > key[x]]; } splay(x); x = key[fndmin(ch[x][1])]; del(root, val); return x; } inline int getrank(int val) { int x = root; while (key[x] != val) { x = ch[x][val > key[x]]; } splay(x); return siz[ch[x][0]] + 1; } inline int getnum(int rank) { int x = root; while (rank <= siz[ch[x][0]] || rank > siz[ch[x][0]] + tm[x]) { if (rank <= siz[ch[x][0]]) { x = ch[x][0]; } else { rank -= siz[ch[x][0]] + tm[x]; x = ch[x][1]; } } return key[x]; } int main(void) { int n; scanf("%d", &n); while (n--) { scanf("%d%d", &t1, &t2); if (t1 == 1) { if (ist(root, t2, 0, 0)) { splay(cnt); } } else if (t1 == 2) { del(root, t2); } else if (t1 == 3) { printf("%d\n", getrank(t2)); } else if (t1 == 4) { printf("%d\n", getnum(t2)); } else if (t1 == 5) { printf("%d\n", qianqu(t2)); } else { printf("%d\n", houji(t2)); } } return 0; }
- bzoj 3224==tyvj 1728普通平衡树 splay
- BZOJ 3224 Tyvj 1728 普通平衡树 (Splay)
- 【Splay】bzoj3224 Tyvj 1728 普通平衡树
- 【BZOJ3224】【codevs4543】【tyvj1728】普通平衡树,第一次的splay
- BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子+SPlay详细讲解
- bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Splay
- [bzoj3224]Tyvj 1728 普通平衡树——splay模板
- bzoj 3224: Tyvj 1728 普通平衡树(splay 模板题)
- 【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树
- [bzoj 3224] Tyvj 1728 普通平衡树(Splay)
- bzoj 3224: Tyvj 1728 普通平衡树 (Splay模板)
- 【bzoj3224】【Tyvj1728】【普通平衡树】【splay】
- BZOJ 3224: Tyvj 1728 普通平衡树 [Splay]【数据结构】
- bzoj 3224 Tyvj 1728 普通平衡树 [Splay]
- [BZOJ]3224: Tyvj 1728 普通平衡树
- 【Treap】[BZOJ 3224]Tyvj 1728 普通平衡树
- 【BZOJ】3224: Tyvj 1728 普通平衡树(某不科学的oj)
- BZOJ 3224: Tyvj 1728 普通平衡树 pb_ds
- BZOJ3224[Tyvj 1728 普通平衡树]题解--Treap