bzoj 3223 文艺平衡树 - Splay
2017-01-15 20:21
309 查看
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3884 Solved: 2235
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果Sample Input
5 31 3
1 3
1 4
Sample Output
4 3 2 1 5HINT
N,M<=100000Source
平衡树[Submit][Status][Discuss]
不是特别难,打个lazy标记就行了,详见[Splay]
/** * bzoj * Problem#3223 * Accepted * Time:2012ms * Memory:4336k */ #include<iostream> #include<fstream> #include<sstream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cctype> #include<cmath> #include<algorithm> #include<stack> #include<queue> #include<set> #include<map> #include<vector> using namespace std; typedef bool boolean; #define smin(a, b) (a) = min((a), (b)) #define smax(a, b) (a) = max((a), (b)) template<typename T> inline void readInteger(T& u){ char x; int aFlag = 1; while(!isdigit((x = getchar())) && x != '-' && x != -1); if(x == -1) return; if(x == '-'){ x = getchar(); aFlag = -1; } for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0'); ungetc(x, stdin); u *= aFlag; } template<typename T> class SplayNode { public: T data; int s; boolean lazy; SplayNode* next[2]; SplayNode* father; SplayNode():s(1), lazy(0){ memset(next, 0, sizeof(next)); } SplayNode(T data, SplayNode* father):data(data), father(father), s(1), lazy(0){ memset(next, 0, sizeof(next)); } int cmp(T a){ if(a == data) return -1; return (a > data) ? (1) : (0); } int getWhich(SplayNode* p){ return (next[0] == p) ? (0) : (1); } void maintain(){ s = 1; for(int i = 0; i < 2; i++) if(next[i] != NULL) s += next[i]->s; } void pushDown(){ swap(next[0], next[1]); for(int i = 0; i < 2; i++) if(next[i] != NULL) next[i]->lazy ^= 1; lazy = false; } }; template<typename T> class Splay { protected: inline static void rotate(SplayNode<T>*& node, int d){ SplayNode<T> *father = node->father; SplayNode<T> *newRoot = node->next[d ^ 1]; if(newRoot->lazy) newRoot->pushDown(); node->next[d ^ 1] = newRoot->next[d]; node->father = newRoot; newRoot->next[d] = node; newRoot->father = father; if(node->next[d ^ 1] != NULL) node->next[d ^ 1]->father = node; if(father != NULL) father->next[father->getWhich(node)] = newRoot; node->maintain(); node->father->maintain(); } static SplayNode<T>* insert(SplayNode<T>*& node, SplayNode<T>* father, T data){ if(node == NULL){ node = new SplayNode<T>(data, father); return node; } int d = node->cmp(data); if(d == -1) return NULL; SplayNode<T>* res = insert(node->next[d], node, data); if(res != NULL) node->maintain(); return res; } static SplayNode<T>* findKth(SplayNode<T>*& node, int k){ if(node->lazy) node->pushDown(); int ls = (node->next[0] != NULL) ? (node->next[0]->s) : (0); if(k >= ls + 1 && k <= ls + 1) return node; if(k <= ls) return findKth(node->next[0], k); return findKth(node->next[1], k - ls - 1); } public: SplayNode<T> *root; Splay(){ } inline void splay(SplayNode<T>* node, SplayNode<T>* father){ if(node == father) return; while(node->father != father){ SplayNode<T>* f = node->father; int fd = f->getWhich(node); SplayNode<T>* ff = f->father; if(ff == father){ rotate(f, fd ^ 1); break; } int ffd = ff->getWhich(f);; if(ffd == fd){ rotate(ff, ffd ^ 1); rotate(f, fd ^ 1); }else{ rotate(f, fd ^ 1); rotate(ff, ffd ^ 1); } } if(father == NULL) root = node; } inline SplayNode<T>* insert(T data){ SplayNode<T>* res = insert(root, NULL, data); if(res != NULL) splay(res, NULL); return res; } inline SplayNode<T>* findKth(int k, SplayNode<T>* father){ if(k <= 0 || k > root->s) return NULL; SplayNode<T>* p = findKth(root, k); splay(p, father); return p; } SplayNode<T>* split(int from, int end){ if(from > end) return NULL; if(from == 1 && end == root->s){ findKth(1, NULL); return this->root; } if(from == 1){ findKth(end + 1, NULL); findKth(from, root); return root->next[0]; } if(end == root->s){ findKth(from - 1, NULL); findKth(end, root); return root->next[1]; } findKth(end + 1, NULL); findKth(from - 1, root); return root->next[0]->next[1]; } void out(SplayNode<T>* node){ if(node == NULL) return; if(node->lazy) node->pushDown(); out(node->next[0]); printf("%d ", node->data); out(node->next[1]); } void debugOut(SplayNode<T>* node){ //调试使用函数,打印Splay if(node == NULL) return; cout << node->data << "(" << node->s << "," << ((node->father == NULL) ? (-9999) : (node->father->data)) << "," << node->lazy << "){"; debugOut(node->next[0]); cout << ","; debugOut(node->next[1]); cout << "}"; } }; int n, m; Splay<int> s; int main(){ readInteger(n); readInteger(m); for(int i = 1; i <= n; i++){ s.insert(i); } for(int i = 1, a, b; i<= m; i++){ readInteger(a); readInteger(b); if(a == b) continue; SplayNode<int>* p = s.split(a, b); p->lazy ^= 1; } s.out(s.root); return 0; }
相关文章推荐
- BZOJ 3223 文艺平衡树 splay
- bzoj 3223 文艺平衡树 Splay 打标志
- 【bzoj3223】文艺平衡树【Splay】【呵呵】
- bzoj 3223 文艺平衡树 Splay详细解析
- 【BZOJ3223】文艺平衡树,Splay反转区间
- BZOJ 3223 文艺平衡树 【Splay】
- [BZOJ3223] 文艺平衡树 - splay
- bzoj 3223 Tyvj 1729 文艺平衡树 Splay
- 【bzoj3223】文艺平衡树 Splay & Treap
- 【bzoj3223】Tyvj 1729 文艺平衡树 Splay
- splay区间翻转bzoj 3223(tyvj 1729)文艺平衡树题解
- _bzoj3223 Tyvj 1729 文艺平衡树【Splay】
- bzoj3223 Tyvj1729 文艺平衡树 splay
- BZOJ_3223: Tyvj 1729 文艺平衡树 _splay
- 【BZOJ3223】Tyvj 1729 文艺平衡树【Splay】
- BZOJ 3223: Tyvj 1729 文艺平衡树 splay
- 【Splay】【块状链表】bzoj3223 Tyvj 1729 文艺平衡树
- [bzoj3223]文艺平衡树——splay
- bzoj 3223 文艺平衡树 Splay
- [BZOJ]3223: Tyvj 1729 文艺平衡树