[Tyvj 1728]普通平衡树
题目
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
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 493598OUTPUT
106465
84185
492737
解题报告
一道裸的平衡树板子题,也是我的Treap首题,留念
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 using namespace std; 6 inline int read(){ 7 int sum(0),f(1); 8 char ch(getchar()); 9 while(ch<'0'||ch>'9'){ 10 if(ch=='-') 11 f=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9'){ 15 sum=sum*10+ch-'0'; 16 ch=getchar(); 17 } 18 return sum*f; 19 } 20 struct node{ 21 int size,key,v; 22 node *ch[2]; 23 node():size(1),key(rand()),v(0){ 24 ch[0]=ch[1]=NULL; 25 } 26 node(int x):size(1),key(rand()),v(x){ 27 ch[0]=ch[1]=NULL; 28 } 29 }*root; 30 inline int get_size(node *x){ 31 if(x==NULL) 32 return 0; 33 return x->size; 34 } 35 inline void pushup(node *rt){ 36 rt->size=get_size(rt->ch[0])+get_size(rt->ch[1])+1; 37 } 38 inline void ro(node *&rt,int d){ 39 node *tmp(rt->ch[d^1]); 40 rt->ch[d^1]=tmp->ch[d]; 41 pushup(rt); 42 tmp->ch[d]=rt; 43 pushup(tmp); 44 rt=tmp; 45 } 46 inline void insert(node *&rt,int x){ 47 if(!rt){ 48 rt=new node(x); 49 return; 50 } 51 int d(rt->v>x); 52 insert(rt->ch[d^1],x); 53 pushup(rt); 54 if(rt->ch[d^1]->key>rt->key) 55 ro(rt,d); 56 } 57 inline void del(node *&rt,int x){ 58 if(rt->v==x){ 59 if(rt->ch[0]!=NULL&&rt->ch[1]!=NULL){ 60 int d(rt->ch[0]->key>rt->ch[1]->key); 61 ro(rt,d); 62 del(rt->ch[d],x); 63 } 64 else{ 65 node *tmp=NULL; 66 if(rt->ch[0]!=NULL) 67 tmp=rt->ch[0]; 68 else 69 tmp=rt->ch[1]; 70 delete rt; 71 rt=tmp; 72 } 73 } 74 else{ 75 int d(rt->v>x); 76 del(rt->ch[d^1],x); 77 } 78 if(rt!=NULL) 79 pushup(rt); 80 } 81 inline int rk(int x){ 82 node *rt(root); 83 int ret(0); 84 while(rt){ 85 if(x>rt->v){ 86 ret+=get_size(rt->ch[0])+1; 87 rt=rt->ch[1]; 88 } 89 else 90 rt=rt->ch[0]; 91 } 92 return ret; 93 } 94 inline int kth(int k){ 95 node *rt(root); 96 while(rt){ 97 if(get_size(rt->ch[0])+1==k) 98 return rt->v; 99 if(get_size(rt->ch[0])+1>k) 100 rt=rt->ch[0]; 101 else{ 102 k-=get_size(rt->ch[0])+1; 103 rt=rt->ch[1]; 104 } 105 } 106 return 0; 107 } 108 inline int gg(){ 109 freopen("phs.in","r",stdin); 110 freopen("phs.out","w",stdout); 111 srand(time(NULL)); 112 int n(read()); 113 while(n--){ 114 int op(read()),x(read()); 115 if(op==1){ 116 insert(root,x); 117 continue; 118 } 119 if(op==2){ 120 del(root,x); 121 continue; 122 } 123 if(op==3){ 124 printf("%d ",rk(x)+1); 125 continue; 126 } 127 if(op==4){ 128 printf("%d ",kth(x)); 129 continue; 130 } 131 if(op==5){ 132 printf("%d ",kth(rk(x))); 133 continue; 134 } 135 if(op==6){ 136 printf("%d ",kth(rk(x+1)+1)); 137 continue; 138 } 139 } 140 } 141 int k(gg()); 142 int main(){;}
玄学板子,调的时间比打的时间还长= =
ps:参数类型一定要写对QWQ