首页 > 代码库 > [题解]bzoj 3223 文艺平衡树
[题解]bzoj 3223 文艺平衡树
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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 文艺平衡树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。