class SplayNode { public: SplayNode *child[2]; char value; int size; bool flip; SplayNode(char c) : value(c), size(1), flip(false) { child[0] = child[1] = NULL; } int getPosition()const { return child[0] ? child[0]->size + 1 : 1; } void maintain() { size = 1; if (child[0]) { size += child[0]->size; } if (child[1]) { size += child[1]->size; } } void pushDown() { if (flip) { swap(child[0], child[1]); for (int i = 0; i < 2; i++) { if (child[i]) { child[i]->flip ^= 1; } } flip = false; } } }; class SplayTree { public: SplayNode *root; SplayTree(char *a, int n); void build(SplayNode *&node, char *begin, char *end); void rotate(SplayNode *&node, int direction); void splay(SplayNode *&node, int position); void reverse(int begin, int end); void traverse(SplayNode *u); void traverse(); }; SplayTree::SplayTree(char *a, int n) { build(root, a, a + n - 1); } void SplayTree::build(SplayNode *&node, char *begin, char *end) { if (begin > end) { return; } char *middle = begin + (end - begin >> 1); node = new SplayNode(*middle); build(node->child[0], begin, middle - 1); build(node->child[1], middle + 1, end); node->maintain(); } void SplayTree::rotate(SplayNode *&node, int direction) { SplayNode *child = node->child[direction ^ 1]; node->child[direction ^ 1] = child->child[direction]; child->child[direction] = node; node->maintain(); child->maintain(); node = child; } void SplayTree::splay(SplayNode *&node, int position) { node->pushDown(); if (node->getPosition() != position) { int d = node->getPosition() < position; SplayNode *node2 = node->child[d]; position -= d ? node->getPosition() : 0; node2->pushDown(); if (node2->getPosition() != position) { int d2 = node2->getPosition() < position; position -= d2 ? node2->getPosition() : 0; splay(node2->child[d2], position); if (d == d2) { rotate(node, d ^ 1); } else { rotate(node->child[d], d); } } rotate(node, d ^ 1); } } void SplayTree::reverse(int begin, int end) { splay(root, begin); splay(root->child[1], end - begin + 2); root->child[1]->child[0]->flip ^= 1; } void SplayTree::traverse(SplayNode *u) { if (!u) { return; } u->pushDown(); traverse(u->child[0]); if (u->value) { printf("%c", u->value); } traverse(u->child[1]); } void SplayTree::traverse() { traverse(root); }
相关文章:
- ZOJ3765 Lights Splay树 2021-09-12
- 伸展树(splay) 2022-12-23
- 平衡树splay 2021-06-18
- Splay 伸展树 2021-06-19
- Splay树分析 2022-12-23
- 树-伸展树(Splay Tree) 2022-12-23
- 伸展树 Splay Tree 2021-09-06