【模板】【bzoj3224】Tyvj 1728 普通平衡树 Splay
2015-12-03 20:30
453 查看
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)Output
对于操作3,4,5,6每行输出一个数,表示对应答案Sample Input
[code]10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598
Sample Output
[code]106465 84185 492737
HINT
1.n的数据范围:n<=1000002.每个数的数据范围:[-1e7,1e7]
Source
平衡树终于把splay艹出来了!!!!!!!!!!!!!
不过还是抄的viv&&小绿的模板 _(: 3
自己悟的splay总是RE之类的……没看书就用指针就是我这种下场……得抽空补一下语言
基础了…………
说一下基本操作:
插入:按普通平衡树那样插入,插入完了splay到根。
删除:splay到根,如果只有一个儿子,则改一下根的指针到那个儿子即可。若有俩儿子,则把这个数的前驱splay到根的左儿子位置上,然后改一下根的指针指向前驱即可。
剩余四个操作看代码就懂了…
splay(p,rt) :把p节点转到父节点为rt的位置上。
rotate(p):把p节点转到父节点的位置上。
附上代码:
[code]#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int SZ = 1000010; const int INF = 1000000010; struct node{ node *ch[2],*f; int sz,cnt,v; void maintain() { sz = cnt + ch[0] -> sz + ch[1] -> sz; } int cmp(int x) { if(x == v) return -1; return x < v ? 0 : 1; } int dir() { return f -> ch[1] == this; } void setc(node *x,int d) { (ch[d] = x) -> f = this; } }T[SZ], *root, *null; int Tcnt = 0; node* newnode(int x,node *f) { node *k = T + (++ Tcnt); k -> v = x; k -> ch[0] = k -> ch[1] = null; k -> sz = k -> cnt = 1; k -> f = f; return k; } void rotate(node *p) { node *fa = p -> f; int d = p -> dir(); fa -> f -> setc(p,fa -> dir()); fa -> setc(p -> ch[d ^ 1],d); fa -> maintain(); p -> setc(fa,d ^ 1); p -> maintain(); if(fa == root) root = p; } void splay(node *p,node *rt = null) { while(p -> f != rt) { if(p -> f -> f == rt) rotate(p); else { if(p -> dir() == p -> f -> dir()) rotate(p -> f),rotate(p); else rotate(p),rotate(p); } } } void insert(node *p,int x) { if(root == null) { root = newnode(x,null); return ; } while(p != null) { p -> sz ++; int d = p -> cmp(x); if(d == -1) { p -> cnt ++; break; } if(p -> ch[d] == null) { p -> ch[d] = newnode(x,p); p = p -> ch[d]; break; } p = p -> ch[d]; } splay(p); } void erase(node *p,int x) { while(p != null) { p -> sz --; int d = p -> cmp(x); if(d == -1) { p -> cnt --; break; } p = p -> ch[d]; } if(p -> cnt) return ; splay(p); if(p -> ch[0] == null) { root = p -> ch[1]; root -> f = null; return ; } if(p -> ch[1] == null) { root = p -> ch[0]; root -> f = null; return ; } p = p -> ch[0]; while(p -> ch[1] != null) p = p -> ch[1]; splay(p,root); p -> ch[1] = root -> ch[1]; p -> ch[1] -> f = p; p -> f = null; p -> maintain(); root = p; } int ask_rank(node *p,int x) { int ans = 0; while(p != null) { int d = p -> cmp(x); if(d == -1) return ans + p -> ch[0] -> sz + 1; if(d == 1) ans += p -> ch[0] -> sz + p -> cnt; p = p -> ch[d]; } return -1; } int ask_num(node *p,int k) { while(p != null) { int l = p -> ch[0] -> sz + 1; int r = p -> ch[0] -> sz + p -> cnt; if(l <= k && k <= r) return p -> v; if(k > r) k -= r,p = p -> ch[1]; else p = p -> ch[0]; } } int ask_pre(node *p,int x) { int ans = 0; while(p != null) { if(p -> v < x) ans = p -> v,p = p -> ch[1]; else p = p -> ch[0]; } return ans; } int ask_suf(node *p,int x) { int ans = 0; while(p != null) { if(p -> v > x) ans = p -> v,p = p -> ch[0]; else p = p -> ch[1]; } return ans; } void init() { null = newnode(-INF,null); null -> sz = null -> cnt = 0; root = null; } int main() { init(); int n; scanf("%d",&n); while(n --) { int opt,x; scanf("%d%d",&opt,&x); switch(opt) { case 1: insert(root,x); break; case 2: erase(root,x); break; case 3: printf("%d\n",ask_rank(root,x)); break; case 4: printf("%d\n",ask_num(root,x)); break; case 5: printf("%d\n",ask_pre(root,x)); break; case 6: printf("%d\n",ask_suf(root,x)); break; } } return 0; }
相关文章推荐
- -webkit-text-size-adjust: none;
- 会计等式
- SQL Server系列(9) -- 数据库的安全与备份
- UI基础3 UIControl
- 驱动测试错误集锦
- android 网络异常提示
- Luence 课程1----索引和搜索的建立
- 欢迎使用CSDN-markdown编辑器
- mysql升级
- 差分约束学习(一)POJ1201
- Android 实现调用照相机和选取本地照片功能
- 有穷自动机
- android 的Drawable
- Hint:Parameter 'in' is declared but never used in 'query_student'
- 迭代器
- 随笔1
- python write出现 Non-character array cannot be interpreted as character buffer.
- windows xp 和 ubuntu双系统出现grub,如何设置直接进入双系统选择界面
- Object-C,NSSet,不可变集合
- Object-C,NSSet,不可变集合