bzoj 3223/tyvj 1729 文艺平衡树 splay tree

原题链接:http://www.tyvj.cn/p/1729 

这道题以前用c语言写的splay tree水过了。。

现在接触了c++重写一遍。。。

只涉及区间翻转,由于没有删除操作故不带垃圾回收,具体如下:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<iostream>
  4 #include<algorithm>
  5 const int MAX_N = 100010;
  6 struct Node{
  7     int v, s, rev;
  8     Node *pre, *ch[2];
  9     inline void set(int _v = 0, int _s = 0, Node *p = NULL){
 10         v = _v, s = _s, rev = 0;
 11         pre =  ch[0] = ch[1] = p;
 12     }
 13     inline void push_up(){
 14         s = ch[0]->s + ch[1]->s + 1;
 15     }
 16     inline void update(){
 17         Node *t = ch[0];
 18         rev ^= 1;
 19         t = ch[0];
 20         ch[0] = ch[1];
 21         ch[1] = t;
 22     }
 23     inline void push_down(){
 24         if (rev != 0){
 25             rev ^= 1;
 26             ch[0]->update();
 27             ch[1]->update();
 28         }
 29     }
 30 };
 31 struct SplayTree{
 32     Node stack[MAX_N];
 33     Node *tail, *root, *null;
 34     inline Node *newNode(int v){
 35         Node *p = tail++;
 36         p->set(v, 1, null);
 37         return p;
 38     }
 39     void initialize(int l, int r){
 40         tail = &stack[0];
 41         null = tail++;
 42         null->set(-1);
 43         root = newNode(-1);
 44         root->ch[1] = newNode(-1);
 45         root->ch[1]->pre = root;
 46         Node *x = built(l, r);
 47         root->ch[1]->ch[0] = x;
 48         x->pre = root->ch[1];
 49         root->ch[1]->push_up();
 50         root->push_up();
 51     }
 52     inline void rotate(Node *x, int c){
 53         Node *y = x->pre;
 54         y->push_down(), x->push_down();
 55         y->ch[!c] = x->ch[c];
 56         x->pre = y->pre;
 57         if (x->ch[c] != null) x->ch[c]->pre = y;
 58         if (y->pre != null) y->pre->ch[y->pre->ch[0] != y] = x;
 59         x->ch[c] = y;
 60         y->pre = x;
 61         y->push_up();
 62         if (y == root) root = x;
 63     }
 64     void splay(Node *x, Node *f){
 65         if (x == root) return;
 66         for (; x->pre != f; x->push_down()){
 67             if (x->pre->pre == f){
 68                 rotate(x, x->pre->ch[0] == x);
 69             } else {
 70                 Node *y = x->pre, *z = y->pre;
 71                 if (z->ch[0] == y){
 72                     if (y->ch[0] == x) 
 73                         rotate(y, 1), rotate(x, 1);
 74                     else rotate(x, 0), rotate(x, 1);
 75                 } else {
 76                     if (y->ch[1] == x) 
 77                         rotate(y, 0), rotate(x, 0);
 78                     else rotate(x, 1), rotate(x, 0);
 79                 }
 80             }
 81         }
 82         x->push_up();
 83     }
 84     Node *built(int l, int r){
 85         Node *p = null;
 86         if (l > r) return null;
 87         int mid = (l + r) >> 1;
 88         p = newNode(mid);
 89         p->ch[0] = built(l, mid - 1);
 90         if (p->ch[0] != null) p->ch[0]->pre = p;
 91         p->ch[1] = built(mid + 1, r);
 92         if (p->ch[1] != null) p->ch[1]->pre = p;
 93         p->push_up();
 94         return p;
 95     }
 96     Node *select(Node *x, int k){
 97         int t = 0;
 98         Node *ret = x;
 99         for (;;){
100             ret->push_down();
101             t = ret->ch[0]->s;
102             if (t == k) break;
103             if (k < t) ret = ret->ch[0];
104             else k -= t + 1, ret = ret->ch[1];
105         }
106         return ret;
107     }
108     void travel(Node *x){
109         if (x != null){
110             x->push_down();
111             travel(x->ch[0]);
112             printf("%d ", x->v);
113             travel(x->ch[1]);
114         }
115     }
116     Node *get_range(int l, int r){
117         splay(select(root, l - 1), null);
118         splay(select(root, r + 1), root);
119         return root->ch[1]->ch[0];
120     }
121     void reverse(int l, int r){
122         Node *ret = get_range(l, r);
123         ret->update();
124     }
125     void print(int n){
126         Node *ret = get_range(1, n);
127         travel(ret);
128     }
129 }Splay;
130 int main(){
131 #ifdef LOCAL
132     freopen("in.txt", "r", stdin);
133     freopen("out.txt", "w+", stdout);
134 #endif
135     int n, m, a, b;
136     while (~scanf("%d %d", &n, &m)){
137         Splay.initialize(1, n);
138         while (m--){
139             scanf("%d %d", &a, &b);
140             Splay.reverse(a, b);
141         }
142         Splay.print(n);
143     }
144     return 0;
145 }
View Code

 

转载于:https://www.cnblogs.com/GadyPu/p/4454338.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值