bzoj3224: Tyvj 1728 普通平衡树

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

106465
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
",e[e[root].ch[0]].siz+1);
141         }
142         if(x==4){printf("%d
",getKth(y));}
143         if(x==5){printf("%d
",getprev(y));}
144         if(x==6){printf("%d
",getsucc(y));}
145     }
146     return 0;
147 }
View Code
原文地址:https://www.cnblogs.com/chadinblog/p/5914375.html