zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    [CTSC2018]暴力写挂
    【bzoj 2870】 最长道路tree
    [CTSC2010]珠宝商
    [JXOI2018]守卫
    [JXOI2018]排序问题
    [AHOI2014/JSOI2014]骑士游戏
    [SNOI2017]遗失的答案
    【LGP5437】【XR-2】约定
    【LGP5349】幂
    hdu-2688 Rotate---树状数组+模拟
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7860085.html
Copyright © 2011-2022 走看看