子树大小平衡树(SizeBalancedTree,SBT)——模板
植树节,种一棵SBT玩玩,跑得不是很快…………不过还好吧…………
求各路神牛轻虐…………………
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 const int INF=0x7fffffff; 8 const int MAXN=1000010; 9 10 struct _Node 11 { 12 int key,size; 13 _Node *s[2]; 14 _Node() {} 15 _Node(int key,int size,_Node *v):key(key),size(size) {s[0]=s[1]=v;} 16 }pool[MAXN],null(0,0,&null); 17 18 int idx; 19 20 class SizeBalancedTree 21 { 22 private: 23 24 _Node *root; 25 26 void _update(_Node* now) 27 { 28 now->size=now->s[0]->size+now->s[1]->size+1; 29 } 30 void _rot(_Node *&now,bool d) 31 { 32 _Node *s=now->s[d]; 33 now->s[d]=s->s[!d]; 34 s->s[!d]=now; 35 _update(now),_update(s); 36 now=s; 37 } 38 void _maintain(_Node *&now,bool d) 39 { 40 if (now==&null) return; 41 _Node *&p=now->s[d]; 42 43 if (p->s[d]->size>now->s[!d]->size) 44 _rot(now,d); 45 else if (p->s[!d]->size>now->s[!d]->size) 46 { 47 _rot(p,!d); 48 _rot(now,d); 49 } 50 else return; 51 _maintain(now->s[0],0); 52 _maintain(now->s[1],1); 53 _maintain(now,0); 54 _maintain(now,1); 55 } 56 void _ins(_Node *&now,int key) 57 { 58 if (now==&null) 59 { 60 now=pool+(idx++); 61 *now=_Node(key,1,&null); 62 return; 63 } 64 bool d=key>now->key; 65 _ins(now->s[d],key); 66 _maintain(now,d); 67 _update(now); 68 } 69 bool _del(_Node *&now,int key) 70 { 71 if (now==&null) return false; 72 bool d,succ; 73 if (now->key==key) 74 { 75 if (now->s[1]==&null) 76 { 77 now=now->s[0]; 78 return true; 79 } 80 else if (now->s[0]==&null) 81 { 82 now=now->s[1]; 83 return true; 84 } 85 _Node *p=now->s[1]; 86 while (p->s[0]!=&null) p=p->s[0]; 87 now->key=p->key; 88 succ=_del(now->s[1],p->key),d=1; 89 } 90 else 91 { 92 d=key>now->key; 93 succ=_del(now->s[d],key); 94 } 95 //_maintain(now,!d); 96 _update(now); 97 return succ; 98 } 99 void _print(_Node *now,int d) 100 { 101 for (int i=1;i<d;++i) printf(" "); 102 if (d) printf("|___"); 103 if (now==&null) printf("null\n"); 104 else 105 { 106 printf("[%d %d]\n",now->key,now->size); 107 _print(now->s[0],d+1); 108 _print(now->s[1],d+1); 109 } 110 } 111 public: 112 113 SizeBalancedTree() { root=&null; } 114 void insert(int k) { _ins(root,k); } 115 bool del(int k) { return _del(root,k); } 116 void print() { _print(root,0); } 117 118 int select(int k) 119 { 120 if (k>root->size) return -1; 121 int z=k-1; 122 _Node *now=root; 123 while (now->s[0]->size!=z) 124 { 125 if (now->s[0]->size<z) now=now->s[1],z-=now->s[0]->size+1; 126 else now=now->s[0]; 127 } 128 return now->key; 129 } 130 int get_rank(int k) 131 { 132 _Node *now=root;int ans=0; 133 while (now!=&null) 134 { 135 if (now->key<k) ans+=now->s[0]->size+1; 136 now=now->s[now->key<k]; 137 } 138 return ans+1; 139 } 140 int get_pre(int k) 141 { 142 _Node *now=root;int ans=-INF; 143 while (now!=&null) 144 { 145 if (now->key<k) ans=max(ans,now->key); 146 if (now->key==k) return k; 147 now=now->s[now->key<k]; 148 } 149 return ans==-INF?-1:ans; 150 } 151 int get_succ(int k) 152 { 153 _Node *now=root;int ans=INF; 154 while (now!=&null) 155 { 156 if (now->key>k) ans=min(ans,now->key); 157 if (now->key==k) return k; 158 now=now->s[now->key<k]; 159 } 160 return ans==INF?-1:ans; 161 } 162 }sbt; 163 164 int main() 165 { 166 char opt[2]; 167 int n,x; 168 freopen("test1.in","r",stdin); 169 freopen("test1_1.out","w",stdout); 170 scanf("%d",&n); 171 while (n--) 172 { 173 scanf("%s%d",opt,&x); 174 switch (opt[0]) 175 { 176 case 'I': 177 sbt.insert(x); 178 break; 179 case 'D': 180 if (!sbt.del(x)) puts("-1"); 181 break; 182 case 'P': 183 printf("%d\n",sbt.get_pre(x)); 184 break; 185 case 'S': 186 printf("%d\n",sbt.get_succ(x)); 187 break; 188 case 'R': 189 printf("%d\n",sbt.get_rank(x)); 190 break; 191 case 'C': 192 printf("%d\n",sbt.select(x)); 193 break; 194 } 195 } 196 return 0; 197 }