[题解]bzoj 3223 文艺平衡树

Posted 阿波罗2003

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解]bzoj 3223 文艺平衡树相关的知识,希望对你有一定的参考价值。

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

4 3 2 1 5

HINT

N,M<=100000

Source

[Submit][Status][Discuss]

    不是特别难,打个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 文艺平衡树的主要内容,如果未能解决你的问题,请参考以下文章

bzoj-3223 文艺平衡树

[BZOJ3223]文艺平衡树

[bzoj3223]文艺平衡树

BZOJ 3223 文艺平衡树

bzoj3223 Tyvj 1729 文艺平衡树

BZOJ3223: Tyvj 1729 文艺平衡树