[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;
}

 

posted @ 2017-11-03 19:24  jzyy  阅读(121)  评论(0编辑  收藏  举报