zoukankan      html  css  js  c++  java
  • [BZOJ3223][tyvj1729]文艺平衡树

    3223: Tyvj 1729 文艺平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 5356  Solved: 3163 [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
     
    对区间维护splay,翻转打标记即可
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int maxn = 100000 + 10;
    int n, m;
    int root, fa[maxn], son[maxn][2], siz[maxn], val[maxn];
    bool tag[maxn] = {false};
    int num[maxn], cnt = 0;
    inline void pushup(int x){
        siz[x] = siz[son[x][0]] + siz[son[x][1]] + 1;
    }
    inline void rotate(int x){
        int y = fa[x], p = son[y][0] == x;
        son[y][!p] = son[x][p];
        fa[son[x][p]] = y;
        fa[x] = fa[y];
        if(fa[x]) son[fa[x]][son[fa[x]][1] == y] = x;
        son[x][p] = y;
        fa[y] = x;
        pushup(y);
    }
    inline void splay(int x, int t){
        int y, z;
        while(fa[x] != t){
            if(fa[fa[x]] == t) rotate(x);
            else{
                y = fa[x];
                z = fa[y];
                if(son[y][0] == x ^ son[z][0] == y) rotate(x);
                else rotate(y);
                rotate(x);
            }
        }
        pushup(x);
        if(!t) root = x;
    }
    inline void pushdown(int x){
        if(tag[x]){
            swap(son[x][0], son[x][1]);
            tag[son[x][0]] ^= 1;
            tag[son[x][1]] ^= 1;
            tag[x] = 0;
        }
    }
    inline void find(int kth, int t){
        int x = root, tmp;
        while(x){
            pushdown(x);
            tmp = siz[son[x][0]];
            if(kth == tmp + 1){
                splay(x, t);
                return;
            }
            if(kth > tmp + 1){
                kth -= tmp + 1;
                x = son[x][1];
            }
            else x = son[x][0];
        }
    }
    int build(int l, int r){
        if(l > r) return 0;
        int now = ++cnt, mid = l + r >> 1;
        val[now] = num[mid];
        siz[now] = 1;
        son[now][0] = build(l, mid - 1);
        if(son[now][0]) fa[son[now][0]] = now;
        son[now][1] = build(mid + 1, r);
        if(son[now][1]) fa[son[now][1]] = now;
        pushup(now);
        return now;
    }
    void init(){
        scanf("%d %d", &n, &m);
        siz[0] = son[0][0] = son[0][1] = 0;
        num[1] = num[n + 2] = 66662333;
        for(int i = 1; i <= n; i++) num[i + 1] = i;
        root = build(1, n + 2);
    }
    void zx(int x){
        if(!x) return;
        pushdown(x);
        zx(son[x][0]);
        printf("%d ", val[x]);
        zx(son[x][1]);
    }
    void work(){
        for(int l, r, i = 1; i <= m; i++){
            scanf("%d %d", &l, &r);
            find(l, 0);
            find(r + 2, root);
            tag[son[son[root][1]][0]] ^= 1;
        }
        find(1, 0);
        find(n + 2, root);
        zx(son[son[root][1]][0]);
    }
    int main(){
        init();
        work();
        return 0;
    }
  • 相关阅读:
    自我介绍
    第一学期第一周学习总结
    2020-2021-1 20201332杨赛 《信息安全专业导论》第一周学习总结
    自我介绍
    2020-2021-1 20201307 《信息安全专业导论》第2周学习总结
    师生关系
    教材快速浏览
    2020-2021-1 20201307 《信息安全专业导论》第一周学习总结
    自我介绍
    20201319《信息安全导论》第一周学习总结
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7780100.html
Copyright © 2011-2022 走看看