平衡树之splay BZOJ3224 普通平衡树
来源:互联网 发布:mac选择office安装路径 编辑:程序博客网 时间:2024/05/29 23:22
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 12204 Solved: 5199
[Submit][Status][Discuss]
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
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
106465
84185
492737
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
Source
平衡树
1 /*f[i]表示i的父结点 2 ch[i][0]表示i的左儿子 3 ch[i][1]表示i的右儿子 4 key[i]表示i的关键字(即结点i代表的那个数字) 5 cnt[i]表示i结点的关键字出现的次数(相当于权值) 6 size[i]表示包括i的这个子树的大小 7 sz为整棵树的大小 8 root为整棵树的根编号 9 */ 10 //借用某神犇的话 没事就多转转 11 #include<iostream> 12 #include<cstdio> 13 #include<cstring> 14 #include<algorithm> 15 using namespace std; 16 17 const int maxn=100010; 18 int f[maxn],ch[maxn][2],key[maxn],cnt[maxn],size[maxn],sz,root; 19 int n,opt,num; 20 21 void clean(int x){//清空 22 ch[x][0]=ch[x][1]=f[x]=cnt[x]=key[x]=size[x]=0; 23 } 24 25 int get(int x){//判断当前点是左还是右 26 return ch[f[x]][1]==x;//?????? 27 } 28 29 void update(int x){//更新size值 30 if(x){ 31 size[x]=cnt[x]; 32 if(ch[x][0]) size[x]+=size[ch[x][0]]; 33 if(ch[x][1]) size[x]+=size[ch[x][1]]; 34 } 35 return; 36 } 37 38 void rotate(int x){ 39 int old=f[x]; 40 int oldf=f[old]; 41 int which=get(x); 42 ch[old][which]=ch[x][which^1]; 43 f[ch[old][which]]=old; 44 f[old]=x; 45 ch[x][which^1]=old; 46 f[x]=oldf; 47 if(oldf) ch[oldf][ch[oldf][1]==old]=x; 48 update(old); 49 update(x); 50 } 51 52 void splay(int x){ 53 for(int fa;fa=f[x];rotate(x)) 54 if(f[fa]) rotate((get(x)==get(fa)?fa:x)); 55 root=x; 56 } 57 58 int find(int v){//查询某数的排名 59 int ans=0; 60 int now=root; 61 while(1){ 62 if(v<key[now]){ 63 now=ch[now][0]; 64 } 65 else{ 66 ans+=(ch[now][0]?size[ch[now][0]]:0); 67 if(v==key[now]){ 68 splay(now); 69 return ans+1; 70 } 71 ans+=cnt[now]; 72 now=ch[now][1]; 73 } 74 } 75 } 76 77 int findx(int x){//查找排名为x的数 78 int now=root; 79 while(1){ 80 if(ch[now][0]&&x<=size[ch[now][0]]) now=ch[now][0]; 81 else{ 82 int temp=(ch[now][0]?size[ch[now][0]]:0)+cnt[now]; 83 if(x<=temp) return key[now]; 84 x-=temp; 85 now=ch[now][1]; 86 } 87 } 88 } 89 90 int pre(){ 91 int now=ch[root][0]; 92 while(ch[now][1]) now=ch[now][1]; 93 return now; 94 } 95 96 int next(){ 97 int now=ch[root][1]; 98 while(ch[now][0]) now=ch[now][0]; 99 return now; 100 }101 102 void del(int x){103 int whatever=find(x);104 if(cnt[root]>1){105 cnt[root]--;106 return;107 }108 if(!ch[root][0]&&!ch[root][1]){109 clean(root);110 root=0;111 return;112 }113 if(!ch[root][0]){114 int oldroot=root;115 root=ch[root][1];116 f[root]=0;117 clean(oldroot);118 return;119 }120 else if(!ch[root][1]){121 int oldroot=root;122 root=ch[root][0];123 f[root]=0;124 clean(oldroot);125 return;126 }127 int leftbig=pre();128 int oldroot=root;129 splay(leftbig);130 f[ch[oldroot][1]]=root;131 ch[root][1]=ch[oldroot][1];132 clean(oldroot);133 update(root);134 return;135 }136 137 void insert(int v){138 if(!root){139 sz++;140 ch[sz][0]=ch[sz][1]=f[sz]=0;141 key[sz]=v;142 cnt[sz]=1;143 size[sz]=1;144 root=sz;145 return;146 }147 int now=root;148 int fa=0;149 while(1){150 if(key[now]==v){151 cnt[now]++;152 update(fa);153 splay(now);154 break;155 }156 fa=now;157 now=ch[now][key[now]<v];//??????158 if(now==0){159 sz++;160 ch[sz][0]=ch[sz][1]=0;161 f[sz]=fa;162 key[sz]=v;163 cnt[sz]=1;164 ch[fa][key[fa]<v]=sz;165 update(fa);166 splay(sz);167 break;168 }169 }170 return;171 } 172 173 int main(){174 scanf("%d",&n);175 for(int i=1;i<=n;i++){176 scanf("%d%d",&opt,&num);177 if(opt==1) insert(num);178 if(opt==2) del(num);179 if(opt==3) printf("%d\n",find(num));180 if(opt==4) printf("%d\n",findx(num));181 if(opt==5){182 insert(num);183 printf("%d\n",key[pre()]);184 del(num);185 } 186 if(opt==6){187 insert(num);188 printf("%d\n",key[next()]);189 del(num);190 }191 }192 return 0;193 }
存作模板
阅读全文
0 0
- bzoj3224普通平衡树 Splay
- [BZOJ3224] 普通平衡树 - splay
- BZOJ3224 普通平衡树(splay)
- [BZOJ3224][SPLAY]普通平衡树
- [BZOJ3224]普通平衡树 SPlay
- bzoj3224普通平衡树splay
- 平衡树之splay BZOJ3224 普通平衡树
- BZOJ3224 普通平衡树 Splay + 替罪羊树
- BZOJ3224普通平衡树splay,SBT代码
- 【BZOJ3224】 【CODEVS4543】 普通平衡树 splay
- bzoj3224 普通平衡树【splay版】
- 【bzoj3224】【Tyvj1728】【普通平衡树】【splay】
- 【bzoj3224】普通平衡树(splay板子)
- bzoj3224 普通平衡树 splay模板题
- [BZOJ3224]普通平衡树
- 【bzoj3224】普通平衡树
- bzoj3224普通平衡树
- BZOJ3224普通平衡树
- PAT程序设计考题——甲级1003(Emergency ) C++实现
- 猥琐的暴搜 NOIP2011 Mayan游戏
- 线段树 hdu1698 Just a Hook
- 倍增LCA code[vs]1036商务旅行
- 线段树 洛谷P1531 I Hate It
- 平衡树之splay BZOJ3224 普通平衡树
- 树状数组 HNOI2002 营业额统计
- 树状数组 NOIP2013 火柴排队
- 最小生成树 HZOI 2016公路修建
- 动态规划入门 COGS1398 最长上升子序列
- 动态规划入门 P1115 最大子段和(链状)
- 动态规划入门 TYVJ 1305 最大子段和(环状)
- KMP kmp模板
- 关于spring的事务面试题