3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3378 Solved: 1379
[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
Sample Output
106465
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
Source
#include<cstdio> #include<cstring> #define N 2001000 using namespace std; struct SBT { int key,cnt; int l,r,size,sc; }s[N]; int root,n,m; void left_rotate(int &x) { int y=s[x].r; s[x].r=s[y].l; s[y].l=x; s[y].size=s[x].size; s[y].sc=s[x].sc; s[x].size=s[s[x].l].size+s[s[x].r].size+1; s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt; x=y; } void right_rotate(int &x) { int y=s[x].l; s[x].l=s[y].r; s[y].r=x; s[y].size=s[x].size; s[y].sc=s[x].sc; s[x].size=s[s[x].l].size+s[s[x].r].size+1; s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt; x=y; } void keep(int &x,int flag) { s[x].size=s[s[x].l].size+s[s[x].r].size+1; s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt; if(!flag) { if(s[s[s[x].l].l].size>s[s[x].r].size)right_rotate(x); else if(s[s[s[x].l].r].size>s[s[x].r].size)left_rotate(s[x].l),right_rotate(x); else return ; } else { if(s[s[s[x].r].r].size>s[s[x].l].size)left_rotate(x); else if(s[s[s[x].r].l].size>s[s[x].l].size)right_rotate(s[x].r),left_rotate(x); else return ; } keep(s[x].l,0); keep(s[x].r,1); keep(x,0); keep(x,1); } void insert(int &x,int key) { if(!x) { x=++n; s[x].size=s[x].sc=s[x].cnt=1; s[x].key=key; } else { if(key==s[x].key)s[x].cnt++,s[x].sc++; else if(key<s[x].key)insert(s[x].l,key),keep(x,0); else insert(s[x].r,key),keep(x,1); } } void del(int &x,int key) { if(s[x].key==key) { if(s[x].cnt>1)s[x].cnt--,s[x].sc--; else if(!s[x].l&&!s[x].r)x=0; else if(!s[x].l*s[x].r)x=s[x].l+s[x].r; else if(s[s[x].l].size>s[s[x].r].size)right_rotate(x),del(s[x].r,key),keep(x,0); else left_rotate(x),del(s[x].l,key),keep(x,1); } else if(key<s[x].key)del(s[x].l,key),keep(x,1); else del(s[x].r,key),keep(x,0); } int find(int &x,int k) { if(s[s[x].l].sc<k&&k<=s[s[x].l].sc+s[x].cnt)return s[x].key; if(k<=s[s[x].l].sc)return find(s[x].l,k); else return find(s[x].r,k-s[s[x].l].sc-s[x].cnt); } int rank(int &x,int key) { if(s[x].key==key)return s[s[x].l].sc+1; if(key<s[x].key)return rank(s[x].l,key); else return rank(s[x].r,key)+s[x].cnt+s[s[x].l].sc; } int getmin() { int x=root; for(;s[x].l;x=s[x].l); return s[x].key; } int getmax() { int x=root; for(;s[x].r;x=s[x].r); return s[x].key; } int pred(int &x,int y,int key) { if(!x)return y; if(key<=s[x].key)return pred(s[x].l,y,key); else return pred(s[x].r,x,key); } int succ(int &x,int y,int key) { if(!x)return y; if(key<s[x].key)return succ(s[x].l,x,key); else return succ(s[x].r,y,key); } int main() { int i,t,x; scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d%d",&t,&x); switch(t) { case 1:insert(root,x);break; case 2:del(root,x);break; case 3:printf("%d\n",rank(root,x));break; case 4:printf("%d\n",find(root,x));break; case 5:printf("%d\n",s[pred(root,0,x)].key);break; case 6:printf("%d\n",s[succ(root,0,x)].key);break; } } return 0; }
时间: 2024-10-06 04:17:27