P3369 【模板】普通平衡树 splay解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | #include <bits/stdc++.h> using namespace std; const int N = 200005; int ch[N][2], par[N], val[N], cnt[N], size[N], ncnt, root; bool chk( int x) { return ch[par[x]][1] == x; } void pushup( int x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x]; } void rotate( int x) { int y = par[x], z = par[y], k = chk(x), w = ch[x][k^1]; ch[y][k] = w; par[w] = y; ch[z][chk(y)] = x; par[x] = z; ch[x][k^1] = y; par[y] = x; pushup(y); pushup(x); } void splay( int x, int goal = 0) { while (par[x] != goal) { int y = par[x], z = par[y]; if (z != goal) { if (chk(x) == chk(y)) rotate(y); else rotate(x); } rotate(x); } if (!goal) root = x; } void insert( int x) { int cur = root, p = 0; while (cur && val[cur] != x) { p = cur; cur = ch[cur][x > val[cur]]; } if (cur) { cnt[cur]++; } else { cur = ++ncnt; if (p) ch[p][x > val[p]] = cur; ch[cur][0] = ch[cur][1] = 0; par[cur] = p; val[cur] = x; cnt[cur] = size[cur] = 1; } splay(cur); } void find( int x) { int cur = root; while (ch[cur][x > val[cur]] && x != val[cur]) { cur = ch[cur][x > val[cur]]; } splay(cur); } int kth( int k) { int cur = root; while (1) { if (ch[cur][0] && k <= size[ch[cur][0]]) { cur = ch[cur][0]; } else if (k > size[ch[cur][0]] + cnt[cur]) { k -= size[ch[cur][0]] + cnt[cur]; cur = ch[cur][1]; } else { splay(cur); return cur; } } } int pre( int x) { find(x); if (val[root] < x) return root; int cur = ch[root][0]; while (ch[cur][1]) cur = ch[cur][1]; splay(cur); return cur; } int succ( int x) { find(x); if (val[root] > x) return root; int cur = ch[root][1]; while (ch[cur][0]) cur = ch[cur][0]; splay(cur); return cur; } void remove( int x) { int last = pre(x), next = succ(x); splay(last); splay(next, last); int del = ch[next][0]; if (cnt[del] > 1) { cnt[del]--; splay(del); } else ch[next][0] = 0; pushup(next), pushup(root); } int n, op, x; int main() { scanf( "%d" , &n); insert(0x3f3f3f3f); insert(0xcfcfcfcf); while (n--) { scanf( "%d%d" , &op, &x); switch (op) { case 1: insert(x); break ; case 2: remove(x); break ; case 3: find(x); printf( "%d\n" , size[ch[root][0]]); break ; case 4: printf( "%d\n" , val[kth(x+1)]); break ; case 5: printf( "%d\n" , val[pre(x)]); break ; case 6: printf( "%d\n" , val[succ(x)]); break ; } } } |
分类:
二叉搜索树BST,平衡树
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!