uva 11922 Permutation Transforme/splay tree

原题链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902
伸展树的区间翻转剪切。。。

如下:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
const int Max_N = 100010;
struct Node{
    int v, s, rev;
    Node *pre, *ch[2];
    inline void set(int _v = -1, int _s = 0, Node *p = NULL){
        v = _v, s = _s, rev = 0;
        pre = ch[0] = ch[1] = p;
    }
    inline void push_up(){
        s = ch[0]->s + ch[1]->s + 1;
    }
    inline void update(){
        rev ^= 1;
        std::swap(ch[0], ch[1]);
    }
    inline void push_down(){
        if (rev != 0){
            rev ^= 1;
            ch[0]->update();
            ch[1]->update();
        }
    }
};
struct SplayTree{
    int N = 0;
    Node *tail, *root, *null, stack[Max_N];
    void init(int n){
        N = n, tail = &stack[0];
        null = tail++;
        null->set();
        root = newNode(-1);
        root->ch[1] = newNode(-1);
        root->ch[1]->pre = root;
        Node *x = built(1, n);
        root->ch[1]->ch[0] = x;
        x->pre = root->ch[1];
        root->ch[1]->push_up();
        root->push_up();
    }
    inline Node *newNode(int v){
        Node *p = tail++;
        p->set(v, 1, null);
        return p;
    }
    Node *built(int l, int r){
        if (l > r) return null;
        int mid = (l + r) >> 1;
        Node *p = newNode(mid);
        p->ch[0] = built(l, mid - 1);
        if (p->ch[0] != null) p->ch[0]->pre = p;
        p->ch[1] = built(mid + 1, r);
        if (p->ch[1] != null) p->ch[1]->pre = p;
        p->push_up();
        return p;
    }
    inline void rotate(Node *x, int c){
        Node *y = x->pre;
        y->push_down(), x->push_down();
        y->ch[!c] = x->ch[c];
        x->pre = y->pre;
        if (x->ch[c] != null) x->ch[c]->pre = y;
        if (y->pre != null) y->pre->ch[y->pre->ch[0] != y] = x;
        x->ch[c] = y;
        y->pre = x;
        y->push_up();
        if (y == root) root = x;
    }
    inline void splay(Node *x, Node *f){
        if (x == root) return;
        for (; x->pre != f; x->push_down()){
            if (x->pre->pre == f){
                rotate(x, x->pre->ch[0] == x);
            } else {
                Node *y = x->pre, *z = y->pre;
                if (z->ch[0] == y){
                    if (y->ch[0] == x) 
                        rotate(y, 1), rotate(x, 1);
                    else rotate(x, 0), rotate(x, 1);
                } else {
                    if (y->ch[1] == x) 
                        rotate(y, 0), rotate(x, 0);
                    else rotate(x, 1), rotate(x, 0);
                }
            }
        }
        x->push_up();
    }
    inline Node *select(Node *x, int k){
        for (int t = 0; x != null;){
            x->push_down();
            t = x->ch[0]->s;
            if (t == k) break;
            else if (k < t) x = x->ch[0];
            else k -= t + 1, x = x->ch[1];
        }
        return x;
    }
    inline Node *get_range(int l, int r){
        splay(select(root, l - 1), null);
        splay(select(root, r + 1), root);
        return root->ch[1]->ch[0];
    }
    inline Node *reverse(int l, int r){
        Node *x = get_range(l, r);
        x->update();
        return x;
    }
    inline void cut_link(int l, int r){
        Node *x = reverse(l, r);
        root->ch[1]->ch[0] = null;
        root->ch[1]->push_up();
        root->push_up();
        int  k = N - r + l - 1;
        get_range(1, k);
        splay(select(root, k), null);
        splay(select(root, k + 1), root);
        root->ch[1]->ch[0] = x;
        x->pre = root->ch[1];
        root->ch[1]->push_up();
        root->push_up();
    }
    inline void travle(Node *x){
        if (x != null){
            x->push_down();
            travle(x->ch[0]);
            printf("%d\n", x->v);
            travle(x->ch[1]);
        }
    }
    inline void travle(){
        get_range(1, N);
        Node *x = root->ch[1]->ch[0];
        travle(x);
    }
}Splay;
int main(){
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w+", stdout);
#endif
    int a, b, n, m;
    while (~scanf("%d %d", &n, &m)){
        Splay.init(n);
        while (m--){
            scanf("%d %d", &a, &b);
            Splay.cut_link(a, b);
        }
        Splay.travle();
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值