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 }
存作模板