# BZOJ 3223: Tyvj 1729 文艺平衡树

## 3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3628  Solved: 2052
[Submit][Status][Discuss]

5 3

1 3

1 3

1 4

4 3 2 1 5

N,M<=100000

## Source

[Submit][Status][Discuss]

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编辑  收藏  举报