BZOJ 3223: Tyvj 1729 文艺平衡树

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3628  Solved: 2052
[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]

 

小生的第三道伸展树板子题。初识Splay维护区间翻转操作。引用一位前辈的题解。、

 

splay的经典操作:翻转区间-->交换左右子树,注意打标记降低翻转次数。如何找到要操作的区间[l,r]:将当前排名(size)为l-1 +1 的节点转到根,将当前排名为r+2的节点转到根的右子树的根节点,则根的右子树的根节点的左子树为所求区间,直接打标记就可以了。

  1 #include <bits/stdc++.h>
  2 
  3 class Splay {
  4 public:
  5     Splay(void) {
  6         root = NULL;
  7         for (top = 0; top < siz; ++top)
  8             stk[top] = tree + top;
  9     }
 10     
 11     inline void auto_build(int n) {
 12         for (int i = 0; i <= n + 1; ++i)
 13             insert(i);
 14     }
 15     
 16     inline void insert(int val) {
 17         if (root == NULL)
 18             root = newnode(val, NULL);
 19         else {
 20             node *t = root;
 21             while (t->son[1] != NULL)
 22                 t = t->son[1];
 23             splay(t, NULL);
 24             t->son[1] = newnode(val, t);
 25             update(root); splay(t->son[1], NULL);
 26         }
 27     }
 28     
 29     inline void reverse(int l, int r) {
 30         ++l, ++r;
 31         splay(rnk(l - 1), NULL);
 32         splay(rnk(r + 1), root);
 33         reverse(root->son[1]->son[0]);
 34     }
 35     
 36     inline void print(int n) {
 37         for (int i = 1; i <= n; ++i)
 38             printf("%d ", rnk(i + 1)->value);
 39     }
 40 private:
 41     const static int siz = 1e5 + 5;
 42     
 43     struct node {
 44         int size;
 45         int value;
 46         bool reverse;
 47         node *father;
 48         node *son[2];
 49     }*root;
 50     
 51     node tree[siz], *stk[siz]; int top;
 52     
 53     inline node *newnode(int v, node *f) {
 54         node *ret = stk[--top];
 55         ret->size = 1;
 56         ret->value = v;
 57         ret->father = f;
 58         ret->son[0] = NULL;
 59         ret->son[1] = NULL;
 60         ret->reverse = false;
 61         return ret;
 62     }
 63     
 64     inline void freenode(node *t) {
 65         stk[top++] = t;
 66     }
 67     
 68     inline int size(node *t) {
 69         return t == NULL ? 0 : t->size;
 70     }
 71     
 72     inline void update(node *t) {
 73         t->size = 1;
 74         t->size += size(t->son[0]);
 75         t->size += size(t->son[1]);
 76     }
 77     
 78     inline bool son(node *f, node *s) {
 79         if (f == NULL)return false;
 80         return f->son[1] == s;
 81     }
 82     
 83     inline bool tag(node *t) {
 84         return t == NULL ? false : t->reverse;
 85     }
 86     
 87     inline void reverse(node *t) {
 88         if (t != NULL)
 89             t->reverse ^= true;
 90     }
 91     
 92     inline void pushdown(node *t) {
 93         if (tag(t)) {
 94             std::swap(t->son[0], t->son[1]);
 95             reverse(t->son[0]);
 96             reverse(t->son[1]);
 97             t->reverse ^= true;
 98         }
 99     }
100     
101     inline void connect(node *f, node *s, bool k) {
102         if (f == NULL)
103             root = s;
104         else
105             f->son[k] = s;
106         if (s != NULL)
107             s->father = f;
108     }
109     
110     inline void rotate(node *t) {
111         node *f = t->father;
112         node *g = f->father;
113         bool a = son(f, t), b = !a;
114         connect(f, t->son[b], a);
115         connect(g, t, son(g, f));
116         connect(t, f, b);
117         update(f);
118         update(t);
119     }
120     
121     inline void splay(node *t, node *p) {if (t)
122         while (t->father != p) {
123             node *f = t->father;
124             node *g = f->father;
125             pushdown(g);
126             pushdown(f);
127             pushdown(t);
128             if (g == p)
129                 rotate(t);
130             else {
131                 if (son(g, f) ^ son(f, t))
132                     rotate(t), rotate(t);
133                 else
134                     rotate(f), rotate(t);
135             }
136         }
137     }
138     
139     inline node *find(int val) {
140         node *ret = root;
141         while (ret != NULL && ret->value != val)
142             pushdown(ret), ret = ret->son[val >= ret->value];
143         return ret;
144     }
145     
146     inline node *rnk(int kth) {
147         for (node *t = root; t; ) {
148             pushdown(t);
149             if (size(t->son[0]) < kth) {
150                 kth -= size(t->son[0]);
151                 if (kth == 1)
152                     return t;
153                 else
154                     --kth, t = t->son[1];
155             }
156             else
157                 t = t->son[0];
158         }
159     }
160 }S;
161 
162 signed main(void) {
163     int n, m; scanf("%d%d", &n, &m);
164     S.auto_build(n);
165     for (int i = 1, l, r; i <= m; ++i)
166         scanf("%d%d", &l, &r), S.reverse(l, r);
167     S.print(n);
168 }

 

@Author: YouSiki

posted @ 2016-12-09 09:53  YouSiki  阅读(179)  评论(0编辑  收藏  举报