标签:
类别:二叉搜索树、二叉查找树或者二叉排序树
在实际应用中,伸展树的中序遍历即为我们维护的数列,这就引出一个问题,怎么在伸展树中表示某个区间?
比如我们要提取区间[a,b],那么我们将a前面一个数对应的结点转到树根,将b 后面一个结点对应的结点转到树根的右边,那么根右边的左子树就对应了区间[a,b]。
原因很简单,将a 前面一个数对应的结点转到树根后, a 及a 后面的数就在根的右子树上,然后又将b后面一个结点对应的结点转到树根的右边,那么[a,b]这个区间就是下图中B所示的子树。
利用区间操作我们可以实现线段树的一些功能,比如回答对区间的询问(最大值,最小值等)。具体可以这样实现,在每个结点记录关于以这个结点为根的子树的信息,然后询问时先提取区间,再直接读取子树的相关信息。还可以对区间进行整体修改,这也要用到与线段树类似的延迟标记技术,即对于每个结点,额外记录一个或多个标记,表示以这个结点为根的子树是否被进行了某种操作,并且这种操作影响其子结点的信息值,当进行旋转和其他一些操作时相应地将标记向下传递。
与线段树相比,伸展树功能更强大,它能解决以下两个线段树不能解决的问题:
(1) 在a后面插入一些数。方法是:首先利用要插入的数构造一棵伸展树,接着,将a 转到根,并将a 后面一个数对应的结点转到根结点的右边,最后将这棵新的子树挂到根右子结点的左子结点上。
(2) 删除区间[a,b]内的数。首先提取[a,b]区间,直接删除即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int MAXN = 100005; 6 const int MAXM = 50005; 7 const int INF = 0x7FFFFFFF; 8 9 class SplayTree 10 { 11 public: 12 SplayTree() 13 { 14 nil = &_nil; 15 _nil.value = 0; 16 _nil.size = 0; 17 _nil.parent = nil; 18 _nil.child[LEFT] = nil; 19 _nil.child[RIGHT] = nil; 20 } 21 22 inline void clear() 23 { 24 nodeNumber = 0; 25 root = nil; 26 insert(-INF); 27 insert(INF); 28 } 29 30 inline void insert(const int value) 31 { 32 if(root == nil) 33 { 34 root = newNode(nil, value); 35 return; 36 } 37 Node *x = root; 38 while(true) 39 { 40 int dir = x->value < value; 41 if(x->child[dir] == nil) 42 { 43 x->child[dir] = newNode(x, value); 44 update(x); 45 splay(x->child[dir], nil); 46 return; 47 } 48 else 49 { 50 x = x->child[dir]; 51 } 52 } 53 } 54 55 inline void remove(const int value) 56 { 57 int k = find(value); 58 find(k - 1, nil); 59 find(k + 1, root); 60 root->child[RIGHT]->child[LEFT] = nil; 61 update(root->child[RIGHT]); 62 update(root); 63 } 64 65 inline int getKth(const int k) 66 { 67 find(k + 1, nil); 68 return root->value; 69 } 70 71 inline void print() 72 { 73 printf("Splay Tree: \n"); 74 print(root); 75 printf("\n"); 76 }private: 77 static const int LEFT = 0; 78 static const int RIGHT = 1; 79 struct Node 80 { 81 int value, size; 82 Node *parent, *child[2]; 83 } _nil, node[MAXN]; 84 int nodeNumber; 85 Node *root, *nil; 86 87 inline Node *newNode(Node *parent, const int value) 88 { 89 node[nodeNumber].value = value; 90 node[nodeNumber].size = 1; 91 node[nodeNumber].parent = parent; 92 node[nodeNumber].child[LEFT] = nil; 93 node[nodeNumber].child[RIGHT] = nil; 94 return &node[nodeNumber++]; 95 } 96 97 inline void update(Node *x) 98 { 99 if(x == nil) 100 { 101 return; 102 } 103 x->size = x->child[LEFT]->size + x->child[RIGHT]->size + 1; 104 } 105 106 inline void rotate(Node *x, const int dir) 107 { 108 Node *p = x->parent; 109 p->child[!dir] = x->child[dir]; 110 p->child[!dir]->parent = p; 111 x->child[dir] = p; 112 x->parent = p->parent; 113 if(p->parent->child[LEFT] == p) 114 { 115 p->parent->child[LEFT] = x; 116 } 117 else 118 { 119 p->parent->child[RIGHT] = x; 120 } 121 p->parent = x; 122 update(p); 123 update(x); 124 if(root == p) 125 { 126 root = x; 127 } 128 } 129 130 inline void splay(Node *x, Node *y) 131 { 132 while(x->parent != y) 133 { 134 if(x->parent->parent == y) 135 { 136 if(x->parent->child[LEFT] == x) 137 { 138 rotate(x, RIGHT); 139 } 140 else 141 { 142 rotate(x, LEFT); 143 } 144 } 145 else if(x->parent->parent->child[LEFT] == x->parent) 146 { 147 if(x->parent->child[LEFT] == x) 148 { 149 rotate(x->parent, RIGHT); 150 rotate(x, RIGHT); 151 } 152 else 153 { 154 rotate(x, LEFT); 155 rotate(x, RIGHT); 156 } 157 } 158 else 159 { 160 if(x->parent->child[RIGHT] == x) 161 { 162 rotate(x->parent, LEFT); 163 rotate(x, LEFT); 164 } 165 else 166 { 167 rotate(x, RIGHT); 168 rotate(x, LEFT); 169 } 170 } 171 update(x); 172 } 173 } 174 175 inline void find(int k, Node *y) 176 { 177 Node *x = root; 178 while(k != x->child[LEFT]->size + 1) 179 { 180 if(k <= x->child[LEFT]->size) 181 { 182 x = x->child[LEFT]; 183 } 184 else 185 { 186 k -= x->child[LEFT]->size + 1; 187 x = x->child[RIGHT]; 188 } 189 } 190 splay(x, y); 191 } 192 193 inline int find(const int value) 194 { 195 Node *x = root; 196 int count = 0; 197 while(true) 198 { 199 if(x->value == value) 200 { 201 return count + x->size - x->child[RIGHT]->size; 202 } 203 else if(x->value > value) 204 { 205 x = x->child[LEFT]; 206 } 207 else 208 { 209 count += x->size - x->child[RIGHT]->size; 210 x = x->child[RIGHT]; 211 } 212 } 213 } 214 215 inline void print(Node *x) 216 { 217 if(x == nil) 218 { 219 return; 220 } 221 printf("%d: %d %d %d\n", x->value, x->child[LEFT]->value, x->child[RIGHT]->value, x->size); 222 print(x->child[LEFT]); 223 print(x->child[RIGHT]); 224 } 225 } splay; 226 227 struct Interval 228 { 229 int a, b, k, index; 230 bool operator < (const Interval &interval) const 231 { 232 return b < interval.b; 233 } 234 } interval[MAXM];int pretty[MAXN];int ans[MAXM]; 235 236 int main() 237 { 238 int n, m; 239 while(~scanf("%d%d", &n, &m)) 240 { 241 for(int i=1;i<=n;++i) 242 { 243 scanf("%d", &pretty[i]); 244 } 245 for(int i=0;i<m;++i) 246 { 247 scanf("%d%d%d", &interval[i].a, &interval[i].b, &interval[i].k); 248 interval[i].index = i; 249 } 250 sort(interval, interval + m); 251 splay.clear(); 252 int a = 1, b = 0; 253 for(int i=0;i<m;++i) 254 { 255 for(int j=a;j<interval[i].a && j<=b;++j) 256 { 257 splay.remove(pretty[j]); 258 } 259 for(int j=max(interval[i].a, b+1);j<=interval[i].b;++j) 260 { 261 splay.insert(pretty[j]); 262 } 263 a = interval[i].a; 264 b = interval[i].b; 265 ans[interval[i].index] = splay.getKth(interval[i].k); 266 } 267 for(int i=0;i<m;++i) 268 { 269 printf("%d\n", ans[i]); 270 } 271 } 272 return 0; 273 }
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int MAXN = 100005; 6 const int MAXM = 100005; 7 const int INF = 0x7fffffff; 8 9 class SplayTree 10 { 11 public: 12 SplayTree() 13 { 14 nil.size = 0; 15 nil.value = INF; 16 nil.min = INF; 17 nil.lchild = &nil; 18 nil.rchild = &nil; 19 nil.parent = &nil; 20 } 21 22 inline void make(int array[], int n) 23 { 24 nodeNumber = 0; 25 int mid = (n - 1) >> 1; 26 root = newNode(&nil, array[mid]); 27 root->lchild = make(0, mid - 1, root, array); 28 root->rchild = make(mid + 1, n - 1, root, array); 29 update(root); 30 } 31 32 inline void ADD(int x, int y, int D) 33 { 34 find(x, &nil); 35 find(y + 2, root); 36 root->rchild->lchild->lazy += D; 37 } 38 39 inline void REVERSE(int x, int y) 40 { 41 find(x, &nil); 42 find(y + 2, root); 43 root->rchild->lchild->isReverse ^= true; 44 } 45 46 inline void REVOLVE(int x, int y, int T) 47 { 48 int len = y - x + 1; 49 T = ((T % len) + len) % len; 50 if(T) 51 { 52 find(y - T + 1, &nil); 53 find(y + 2, root); 54 SplayNode *d = root->rchild->lchild; 55 root->rchild->lchild = &nil; 56 find(x, &nil); 57 find(x + 1, root); 58 root->rchild->lchild = d; 59 d->parent = root->rchild; 60 } 61 } 62 63 inline void INSERT(int x, int P) 64 { 65 find(x + 1, &nil); 66 find(x + 2, root); 67 root->rchild->lchild = newNode(root->rchild, P); 68 } 69 70 inline void DELETE(int x) 71 { 72 find(x, &nil); 73 find(x + 2, root); 74 root->rchild->lchild = &nil; 75 } 76 77 inline void MIN(int x, int y) 78 { 79 find(x, &nil); 80 find(y + 2, root); 81 pushdown(root->rchild->lchild); 82 printf("%d\n", root->rchild->lchild->min); 83 } 84 85 inline void print() 86 { 87 printf("Splay Linear: \n"); 88 print(root); 89 printf("\n"); 90 } 91 92 inline void prints() 93 { 94 printf("Splay Structure: \n"); 95 prints(root); 96 printf("\n"); 97 } 98 99 private: 100 struct SplayNode 101 { 102 int value, size, lazy; 103 SplayNode *parent, *lchild, *rchild; 104 int min; 105 bool isReverse; 106 } nil, node[MAXN + MAXM]; 107 int nodeNumber; 108 SplayNode *root; 109 110 inline SplayNode *newNode(SplayNode *parent, const int value) 111 { 112 node[nodeNumber].value = value; 113 node[nodeNumber].size = 1; 114 node[nodeNumber].lazy = 0; 115 node[nodeNumber].parent = parent; 116 node[nodeNumber].lchild = &nil; 117 node[nodeNumber].rchild = &nil; 118 node[nodeNumber].min = value; 119 node[nodeNumber].isReverse = false; 120 return &node[nodeNumber++]; 121 } 122 123 SplayNode *make(int l, int r, SplayNode *parent, int array[]) 124 { 125 if(l > r) 126 { 127 return &nil; 128 } 129 int mid = (l + r) >> 1; 130 SplayNode *x = newNode(parent, array[mid]); 131 x->lchild = make(l, mid - 1, x, array); 132 x->rchild = make(mid + 1, r, x, array); 133 update(x); 134 return x; 135 } 136 137 inline void update(SplayNode *x) 138 { 139 if(x == &nil) 140 { 141 return; 142 } 143 x->size = x->lchild->size + x->rchild->size + 1; 144 x->min = min(x->value, min(x->lchild->min, x->rchild->min)); 145 } 146 147 inline void pushdown(SplayNode *x) 148 { 149 if(x == &nil) 150 { 151 return; 152 } 153 if(x->isReverse) 154 { 155 swap(x->lchild, x->rchild); 156 x->lchild->isReverse ^= true; 157 x->rchild->isReverse ^= true; 158 x->isReverse = false; 159 } 160 if(x->lazy) 161 { 162 x->value += x->lazy; 163 x->min += x->lazy; 164 x->lchild->lazy += x->lazy; 165 x->rchild->lazy += x->lazy; 166 x->lazy = 0; 167 } 168 } 169 170 inline void rotateLeft(SplayNode *x) 171 { 172 SplayNode *p = x->parent; 173 pushdown(x->lchild); 174 pushdown(x->rchild); 175 pushdown(p->lchild); 176 p->rchild = x->lchild; 177 p->rchild->parent = p; 178 x->lchild = p; 179 x->parent = p->parent; 180 if(p->parent->lchild == p) 181 { 182 p->parent->lchild = x; 183 } 184 else 185 { 186 p->parent->rchild = x; 187 } 188 p->parent = x; 189 update(p); 190 update(x); 191 if(root == p) 192 { 193 root = x; 194 } 195 } 196 197 inline void rotateRight(SplayNode *x) 198 { 199 SplayNode *p = x->parent; 200 pushdown(x->lchild); 201 pushdown(x->rchild); 202 pushdown(p->rchild); 203 p->lchild = x->rchild; 204 p->lchild->parent = p; 205 x->rchild = p; 206 x->parent = p->parent; 207 if(p->parent->lchild == p) 208 { 209 p->parent->lchild = x; 210 } 211 else 212 { 213 p->parent->rchild = x; 214 } 215 p->parent = x; 216 update(p); 217 update(x); 218 if(root == p) 219 { 220 root = x; 221 } 222 } 223 224 inline void splay(SplayNode *x, SplayNode *y) 225 { 226 pushdown(x); 227 while(x->parent != y) 228 { 229 if(x->parent->parent == y) 230 { 231 if(x->parent->lchild == x) 232 { 233 rotateRight(x); 234 } 235 else 236 { 237 rotateLeft(x); 238 } 239 } 240 else if(x->parent->parent->lchild == x->parent) 241 { 242 if(x->parent->lchild == x) 243 { 244 rotateRight(x->parent); 245 rotateRight(x); 246 } 247 else 248 { 249 rotateLeft(x); 250 rotateRight(x); 251 } 252 } 253 else 254 { 255 if(x->parent->rchild == x) 256 { 257 rotateLeft(x->parent); 258 rotateLeft(x); 259 } 260 else 261 { 262 rotateRight(x); 263 rotateLeft(x); 264 } 265 } 266 } 267 update(x); 268 } 269 270 inline void find(int k, SplayNode *y) 271 { 272 SplayNode *x = root; 273 pushdown(x); 274 while(k != x->lchild->size + 1) 275 { 276 if(k <= x->lchild->size) 277 { 278 x = x->lchild; 279 } 280 else 281 { 282 k -= x->lchild->size + 1; 283 x = x->rchild; 284 } 285 pushdown(x); 286 } 287 splay(x, y); 288 } 289 290 inline void print(SplayNode *x) 291 { 292 if(x == &nil) 293 { 294 return; 295 } 296 pushdown(x); 297 print(x->lchild); 298 printf("%d: %d %d %d %d\n", x->value, x->min, x->parent->value, x->lchild->value, x->rchild->value); 299 print(x->rchild); 300 } 301 302 inline void prints(SplayNode *x) 303 { 304 if(x == &nil) 305 { 306 return; 307 } 308 pushdown(x); 309 if(x->value == INF) 310 { 311 printf("INF : "); 312 } 313 else 314 { 315 printf("%d : ", x->value); 316 } 317 if(x->lchild == &nil) 318 { 319 printf("nil "); 320 } 321 else 322 { 323 if(x->lchild->value == INF) 324 { 325 printf("INF "); 326 } 327 else 328 { 329 printf("%d ", x->lchild->value); 330 } 331 } 332 if(x->rchild == &nil) 333 { 334 printf("nil\n"); 335 } 336 else 337 { 338 if(x->rchild->value == INF) 339 { 340 printf("INF\n"); 341 } 342 else 343 { 344 printf("%d\n", x->rchild->value); 345 } 346 } 347 prints(x->lchild); 348 prints(x->rchild); 349 } 350 } splayTree; 351 352 char buffer[128];int array[MAXN];int n, m; 353 354 int main() 355 { 356 int x, y, D, T, P; 357 scanf("%d", &n); 358 for(int i=1;i<=n;++i) 359 { 360 scanf("%d", &array[i]); 361 } 362 array[0] = INF; 363 array[n+1] = INF; 364 splayTree.make(array, n + 2); 365 scanf("%d", &m); 366 while(m--) 367 { 368 scanf("%s", buffer); 369 switch(buffer[0]) 370 { 371 case ‘A‘: 372 scanf("%d%d%d", &x, &y, &D); 373 splayTree.ADD(x, y, D); 374 break; 375 case ‘R‘: 376 if(‘E‘ == buffer[3]) 377 { 378 scanf("%d%d", &x, &y); 379 splayTree.REVERSE(x, y); 380 } 381 else 382 { 383 scanf("%d%d%d", &x, &y, &T); 384 splayTree.REVOLVE(x, y, T); 385 } 386 break; 387 case ‘I‘: 388 scanf("%d%d", &x, &P); 389 splayTree.INSERT(x, P); 390 break; 391 case ‘D‘: 392 scanf("%d", &x); 393 splayTree.DELETE(x); 394 break; 395 case ‘M‘: 396 scanf("%d%d", &x, &y); 397 splayTree.MIN(x, y); 398 break; 399 } 400 } 401 return 0; 402 }
标签:
原文地址:http://www.cnblogs.com/wyj-jenny/p/5771561.html