bzoj3224: Tyvj 1728 普通平衡树
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 8649 Solved: 3661
[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.每个数的数据范围:[-1e7,1e7]
用splay写的第一道题;
这题数据很奇葩,我最初写的程序是无法处理重复的情况的,没办法加了暴力判断;
最后加上了合适的处理后,我发现程序比原来慢了...
比较神奇,大概出题人不想卡人吧。
splay模板题:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<cstdlib> 7 using namespace std; 8 int cnt=0,root=0; 9 const int maxn=101000; 10 struct node{ 11 int key,siz,fa,ch[2]; 12 int h; 13 void set(int x,int y,int vv){key=x,siz=y,fa=vv,ch[0]=ch[1]=0;h=1;} 14 }e[maxn]; 15 16 void updata(int x){e[x].siz=e[e[x].ch[0]].siz+e[e[x].ch[1]].siz+e[x].h;} 17 void rotate(int x,int d){//旋转 18 int y=e[x].fa; 19 e[x].fa=e[y].fa; 20 e[e[x].ch[d^1]].fa=y; 21 e[y].fa=x; 22 //以上解决fa域 23 if(e[x].fa) 24 e[e[x].fa].ch[ y== e[e[x].fa].ch[1] ]=x; 25 e[y].ch[d]=e[x].ch[d^1]; 26 e[x].ch[d^1]=y; 27 //以上解决ch域 28 updata(y);updata(x); 29 //以上解决siz域 30 } 31 void splay(int x,int S){//伸展操作 32 while(e[x].fa!=S){ 33 if(e[e[x].fa].fa==S)rotate(x,e[e[x].fa].ch[1]==x);//第一种情况 34 else { 35 int y=e[x].fa,z=e[y].fa; 36 int d=(e[z].ch[1]==y); 37 if(e[y].ch[d]==x) 38 rotate(y,d),rotate(x,d); 39 else 40 rotate(x,d^1),rotate(x,d); 41 } 42 } 43 if(S==0)root=x; 44 } 45 int find(int key){//find key 位置 46 int x=root; 47 while(x&&e[x].key!=key)x=e[x].ch[key>e[x].key]; 48 if(x)splay(x,0); 49 return x; 50 } 51 void insert(int key){//插入 52 if(!root)e[root=++cnt].set(key,1,0); 53 else { 54 int x=root,y=0; 55 while(x&&e[x].key!=key){ 56 y=x; 57 x=e[x].ch[key>e[x].key]; 58 } 59 if(e[x].key==key){ 60 splay(x,0); 61 e[x].h++; 62 updata(x); 63 } 64 else{ 65 e[x=++cnt].set(key,1,y); 66 e[y].ch[key>e[y].key]=x; 67 splay(x,0); 68 } 69 } 70 } 71 void delet(int key){//delete 72 int x=find(key); 73 if(!x)return; 74 if(e[x].h>1){ 75 splay(x,0); 76 e[x].h--; 77 updata(x); 78 return; 79 } 80 int y=e[x].ch[0],z=e[x].ch[1]; 81 while(e[y].ch[1])y=e[y].ch[1]; 82 while(e[z].ch[0])z=e[z].ch[0]; 83 if(!y&&!z){root=0;return;} 84 if(!y){ 85 splay(z,0);e[z].ch[0]=0;updata(z); 86 return; 87 } 88 if(!z){ 89 splay(y,0);e[y].ch[1]=0;updata(y); 90 return; 91 } 92 splay(y,0);splay(z,y); 93 e[z].ch[0]=0; 94 updata(z);updata(y); 95 } 96 int getKth(int k){//find Kth key 97 if(!root)return 0; 98 int x=root; 99 while(x){ 100 if(k>=e[e[x].ch[0]].siz+1&&k<=e[e[x].ch[0]].siz+e[x].h)break; 101 if(k>e[e[x].ch[0]].siz+e[x].h) 102 k-=(e[e[x].ch[0]].siz+e[x].h),x=e[x].ch[1]; 103 else x=e[x].ch[0]; 104 } 105 splay(x,0); 106 return e[x].key; 107 } 108 int getprev(int key){ 109 int x=root; 110 int k=0;e[0].key=-100000000; 111 while(x){ 112 if(e[x].key<key&&e[x].key>e[k].key)k=x; 113 if(e[x].key<key)x=e[x].ch[1]; 114 if(e[x].key>=key)x=e[x].ch[0]; 115 }e[0].key=0; 116 return e[k].key; 117 } 118 int getsucc(int key){ 119 int x=root; 120 int k=0;e[0].key=100000000; 121 while(x){ 122 if(e[x].key>key&&e[x].key<e[k].key)k=x; 123 if(e[x].key>key)x=e[x].ch[0]; 124 if(e[x].key<=key)x=e[x].ch[1]; 125 }e[0].key=0; 126 return e[k].key; 127 } 128 int main(){ 129 int n; 130 scanf("%d",&n); 131 int x,y; 132 int last=0; 133 for(int j=1;j<=n;j++){ 134 scanf("%d%d",&x,&y); 135 if(x==1)insert(y); 136 if(x==2)delet(y); 137 if(x==3){ 138 int o=find(y); 139 splay(o,0); 140 printf("%d\n",e[e[root].ch[0]].siz+1); 141 } 142 if(x==4){printf("%d\n",getKth(y));} 143 if(x==5){printf("%d\n",getprev(y));} 144 if(x==6){printf("%d\n",getsucc(y));} 145 } 146 return 0; 147 }