BZOJ 3223 文艺平衡树

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 5402  Solved: 3196
[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

HINT

N,M<=100000

Source

平衡树

正如sourse所说这是一道平衡树的题目,treep对于区间维护好像并不太擅长

我们用splay,splay改变序列是靠中序遍历的不同,区间反转维护lazy标记即可

#include <bits/stdc++.h>
#define ll long long
#define inf 10000100
using namespace std;
inline int read(){
    int x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int MAXN=1e6+10;
namespace zhangenming{
    int son[MAXN][2],n,m,siz[MAXN],rev[MAXN]={},fa[MAXN],a[MAXN],tot,key[MAXN],root=0;
    inline void push_up(int x){
        siz[x]=siz[son[x][1]]+siz[son[x][0]]+1;
    }
    inline int get(int x){
        return x==son[fa[x]][1];
    }
    inline void push_down(int x){
        if(!x||!rev[x]) return;
        rev[son[x][1]]^=1;rev[son[x][0]]^=1;
        swap(son[x][1],son[x][0]);
        rev[x]=0;
    }
    inline void rote(int x){
        push_down(x);push_down(fa[x]);
        int oldl=fa[x];int wei=get(x);int oldf=fa[fa[x]];
        son[oldl][wei]=son[x][wei^1];fa[son[oldl][wei]]=oldl;
        fa[x]=oldf;fa[oldl]=x;son[x][wei^1]=oldl;
        if(oldf){
            son[oldf][son[oldf][1]==oldl]=x;
        }
        push_up(x);push_up(oldl);
    }
    inline int build(int leftt,int rightt,int root){
        if(leftt>rightt) return 0;
        int mid=(rightt+leftt)>>1;
        int now=++tot;
        rev[now]=0;fa[now]=root;key[now]=a[mid];
        int lefttchild=build(leftt,mid-1,now);
        int righttchild=build(mid+1,rightt,now);
        son[now][0]=lefttchild;son[now][1]=righttchild;push_up(now);
        return now;
    }
    inline void splay(int xx,int tal){
        for(int f;(f=fa[xx])!=tal;rote(xx)){
            if(fa[f]!=tal){
                rote(get(f)==get(xx)?f:xx);
            }
        }
        if(tal==0) root=xx;
    }
    inline int find(int xx){
        int now=root;
        while(1){
            push_down(now);
            if(xx==0) return now;
            if(xx<=siz[son[now][0]]){
                now=son[now][0];
            }
            else{
                xx-=siz[son[now][0]]+1; 
                if(xx==0) return now;
                now=son[now][1];
            }
        }
    }
    void print(int root){
        push_down(root);
        if(son[root][0]) print(son[root][0]);
        if(key[root]!=inf&&key[root]!=-inf) printf("%d ",key[root]);
        if(son[root][1]) print(son[root][1]);
    }
    void init(){
        n=read();m=read();
        a[1]=inf;a[n+2]=-inf;
        for(int i=1;i<=n;i++){
            a[i+1]=i;
        }
        root=build(1,n+2,0);
    }
    inline void printt(){
        for(int i=1;i<=n+2;i++){
            cout<<son[i][0]<<' '<<son[i][1]<<endl;
        }
    }
    void solve(){
        while(m--){
            int xx=read();int yy=read();
            if(xx>=yy) continue;
            xx=find(xx);yy=find(yy+2);
            splay(xx,0);splay(yy,xx);
            rev[son[son[root][1]][0]]^=1;
        }
        print(root);
    }
}
int main(){
    //freopen("All.in","r",stdin);
    //freopen("a.out","w",stdout);
    using namespace zhangenming;
    init();
    solve();
    return 0;
}

  

 

 

posted @ 2017-11-19 16:02  zhangenming  阅读(147)  评论(0编辑  收藏  举报