[题解]bzoj 3223 文艺平衡树
Posted 阿波罗2003
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解]bzoj 3223 文艺平衡树相关的知识,希望对你有一定的参考价值。
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 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
5 3
1 3
1 3
1 4
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source
不是特别难,打个lazy标记就行了,详见[Splay]
1 /** 2 * bzoj 3 * Problem#3223 4 * Accepted 5 * Time:2012ms 6 * Memory:4336k 7 */ 8 #include<iostream> 9 #include<fstream> 10 #include<sstream> 11 #include<cstdio> 12 #include<cstdlib> 13 #include<cstring> 14 #include<ctime> 15 #include<cctype> 16 #include<cmath> 17 #include<algorithm> 18 #include<stack> 19 #include<queue> 20 #include<set> 21 #include<map> 22 #include<vector> 23 using namespace std; 24 typedef bool boolean; 25 #define smin(a, b) (a) = min((a), (b)) 26 #define smax(a, b) (a) = max((a), (b)) 27 template<typename T> 28 inline void readInteger(T& u){ 29 char x; 30 int aFlag = 1; 31 while(!isdigit((x = getchar())) && x != \'-\' && x != -1); 32 if(x == -1) return; 33 if(x == \'-\'){ 34 x = getchar(); 35 aFlag = -1; 36 } 37 for(u = x - \'0\'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - \'0\'); 38 ungetc(x, stdin); 39 u *= aFlag; 40 } 41 42 template<typename T> 43 class SplayNode { 44 public: 45 T data; 46 int s; 47 boolean lazy; 48 SplayNode* next[2]; 49 SplayNode* father; 50 SplayNode():s(1), lazy(0){ 51 memset(next, 0, sizeof(next)); 52 } 53 SplayNode(T data, SplayNode* father):data(data), father(father), s(1), lazy(0){ 54 memset(next, 0, sizeof(next)); 55 } 56 int cmp(T a){ 57 if(a == data) return -1; 58 return (a > data) ? (1) : (0); 59 } 60 int getWhich(SplayNode* p){ 61 return (next[0] == p) ? (0) : (1); 62 } 63 void maintain(){ 64 s = 1; 65 for(int i = 0; i < 2; i++) 66 if(next[i] != NULL) 67 s += next[i]->s; 68 } 69 void pushDown(){ 70 swap(next[0], next[1]); 71 for(int i = 0; i < 2; i++) 72 if(next[i] != NULL) 73 next[i]->lazy ^= 1; 74 lazy = false; 75 } 76 }; 77 78 template<typename T> 79 class Splay { 80 protected: 81 inline static void rotate(SplayNode<T>*& node, int d){ 82 SplayNode<T> *father = node->father; 83 SplayNode<T> *newRoot = node->next[d ^ 1]; 84 if(newRoot->lazy) newRoot->pushDown(); 85 node->next[d ^ 1] = newRoot->next[d]; 86 node->father = newRoot; 87 newRoot->next[d] = node; 88 newRoot->father = father; 89 if(node->next[d ^ 1] != NULL) node->next[d ^ 1]->father = node; 90 if(father != NULL) father->next[father->getWhich(node)] = newRoot; 91 node->maintain(); 92 node->father->maintain(); 93 } 94 95 static SplayNode<T>* insert(SplayNode<T>*& node, SplayNode<T>* father, T data){ 96 if(node == NULL){ 97 node = new SplayNode<T>(data, father); 98 return node; 99 } 100 int d = node->cmp(data); 101 if(d == -1) return NULL; 102 SplayNode<T>* res = insert(node->next[d], node, data); 103 if(res != NULL) node->maintain(); 104 return res; 105 } 106 107 static SplayNode<T>* findKth(SplayNode<T>*& node, int k){ 108 if(node->lazy) node->pushDown(); 109 int ls = (node->next[0] != NULL) ? (node->next[0]->s) : (0); 110 if(k >= ls + 1 && k <= ls + 1) return node; 111 if(k <= ls) return findKth(node->next[0], k); 112 return findKth(node->next[1], k - ls - 1); 113 } 114 115 public: 116 SplayNode<T> *root; 117 118 Splay(){ } 119 120 inline void splay(SplayNode<T>* node, SplayNode<T>* father){ 121 if(node == father) return; 122 while(node->father != father){ 123 SplayNode<T>* f = node->father; 124 int fd = f->getWhich(node); 125 SplayNode<T>* ff = f->father; 126 if(ff == father){ 127 rotate(f, fd ^ 1); 128 break; 129 } 130 int ffd = ff->getWhich(f);; 131 if(ffd == fd){ 132 rotate(ff, ffd ^ 1); 133 rotate(f, fd ^ 1); 134 }else{ 135 rotate(f, fd ^ 1); 136 rotate(ff, ffd ^ 1); 137 } 138 } 139 if(father == NULL) 140 root = node; 141 } 142 143 inline SplayNode<T>* insert(T data){ 144 SplayNode<T>* res = insert(root, NULL, data); 145 if(res != NULL) splay(res, NULL); 146 return res; 147 } 148 149 inline SplayNode<T>* findKth(int k, SplayNode<T>* father){ 150 if(k <= 0 || k > root->s) return NULL; 151 SplayNode<T>* p = findKth(root, k); 152 splay(p, father); 153 return p; 154 } 155 156 SplayNode<T>* split(int from, int end){ 157 if(from > end) return NULL; 158 if(from == 1 && end == root->s){ 159 findKth(1, NULL); 160 return this->root; 161 } 162 if(from == 1){ 163 findKth(end + 1, NULL); 164 findKth(from, root); 165 return root->next[0]; 166 } 167 if(end == root->s){ 168 findKth(from - 1, NULL); 169 findKth(end, root); 170 return root->next[1]; 171 } 172 findKth(end + 1, NULL); 173 findKth(from - 1, root); 174 return root->next[0]->next[1]; 175 } 176 177 void out(SplayNode<T>* node){ 178 if(node == NULL) return; 179 if(node->lazy) node->pushDown(); 180 out(node->next[0]); 181 printf("%d ", node->data); 182 out(node->next[1]); 183 } 184 185 void debugOut(SplayNode<T>* node){ //调试使用函数,打印Splay 186 if(node == NULL) return; 187 cout << node->data << "(" << node->s << "," << ((node->father == NULL) ? (-9999) : (node->father->data)) << "," << node->lazy << "){"; 188 debugOut(node->next[0]); 189 cout << ","; 190 debugOut(node->next[1]); 191 cout << "}"; 192 } 193 }; 194 195 int n, m; 196 Splay<int> s; 197 198 int main(){ 199 readInteger(n); 200 readInteger(m); 201 for(int i = 1; i <= n; i++){ 202 s.insert(i); 203 } 204 for(int i = 1, a, b; i<= m; i++){ 205 readInteger(a); 206 readInteger(b); 207 if(a == b) continue; 208 SplayNode<int>* p = s.split(a, b); 209 p->lazy ^= 1; 210 } 211 s.out(s.root); 212 return 0; 213 }
以上是关于[题解]bzoj 3223 文艺平衡树的主要内容,如果未能解决你的问题,请参考以下文章