zoukankan      html  css  js  c++  java
  • BZOJ3223: Tyvj 1729 文艺平衡树

    【传送门:BZOJ3223


    简要题意:

      给出一个长度为n的序列,第i个数为i

      给出多个操作,给出l,r,代表将序列中l到r的数翻转

      然后输出最后的序列


    题解:

      SPLAY,注意在翻转一个区间后,要打个翻转标记,访问到儿子区间的时候要翻转一下


    参考代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node
    {
        int d,f,c,son[2];
        bool fz;
        node(){fz=false;}
    }tr[110000];int root,len;
    void update(int x)
    {
        int lc=tr[x].son[0],rc=tr[x].son[1];
        tr[x].c=tr[lc].c+tr[rc].c+1;
    }
    void rotate(int x,int w)
    {
        int f=tr[x].f,ff=tr[f].f;
        int R,r;
        
        R=f;r=tr[x].son[w];
        if(r!=0)tr[r].f=R;
        tr[R].son[1-w]=r;
        
        R=ff;r=x;
        tr[r].f=R;
        if(tr[R].son[0]==f)tr[R].son[0]=r;
        else                tr[R].son[1]=r;
        
        R=x;r=f;
        tr[r].f=R;
        tr[R].son[w]=r;
        
        update(f);
        update(x);
    }
    void weihufz(int x)
    {
        tr[x].fz=false;
        swap(tr[x].son[0],tr[x].son[1]);
        int lc=tr[x].son[0],rc=tr[x].son[1];
        tr[lc].fz=1-tr[lc].fz;
        tr[rc].fz=1-tr[rc].fz;
    }
    void splay(int x,int rt)
    {
        while(tr[x].f!=rt)
        {
            int f=tr[x].f,ff=tr[f].f;
            if(ff==rt)
            {
                if(tr[x].fz==true)weihufz(f);
                if(tr[f].son[0]==x)rotate(x,1);
                else                rotate(x,0);
            }
            else
            {
                if(tr[x].fz==true)weihufz(x);
                if(tr[f].fz==true){tr[f].fz=false;tr[x].fz=true;}
                     if(tr[f].son[0]==x&&tr[ff].son[0]==f){rotate(f,1);rotate(x,1);}
                else if(tr[f].son[1]==x&&tr[ff].son[1]==f){rotate(f,0);rotate(x,0);}
                else if(tr[f].son[0]==x&&tr[ff].son[1]==f){rotate(x,1);rotate(x,0);}
                else if(tr[f].son[1]==x&&tr[ff].son[0]==f){rotate(x,0);rotate(x,1);}
            }
        }
        if(rt==0)root=x;
    }
    int ins(int l,int r)
    {
        if(l>r)return 0;
        int mid=(l+r)/2;
        len++;int now=len;
        tr[now].d=mid;
        int lc=ins(l,mid-1),rc=ins(mid+1,r);
        
        if(lc!=0)tr[lc].f=now;
        if(rc!=0)tr[rc].f=now;
        tr[now].son[0]=lc;tr[now].son[1]=rc;
        
        tr[now].c=tr[lc].c+tr[rc].c+1;
        return now;
    }
    int finddizhi(int k)
    { 
        int x=root;
        while(1)
        {
            if(tr[x].fz==true)weihufz(x);
            int lc=tr[x].son[0],rc=tr[x].son[1];
                 if(k<=tr[lc].c)x=lc;
            else if(tr[lc].c+1<k){k-=tr[lc].c+1;x=rc;}
            else break;
        }
        return x;
    }
    void fanzhuan(int l,int r)
    {
        int lc=finddizhi(l-1),rc=finddizhi(r+1);
        splay(lc,0);splay(rc,lc);
        int x=tr[rc].son[0];
        tr[x].fz=1-tr[x].fz;
        splay(x,0);
    }
    int a[110000],alen;
    void dfs(int x)
    {
        if(tr[x].fz==true)weihufz(x);
        int lc=tr[x].son[0],rc=tr[x].son[1];
        if(lc==0&&rc==0){a[++alen]=tr[x].d;return ;}
        if(lc!=0)dfs(lc);
        a[++alen]=tr[x].d;
        if(rc!=0)dfs(rc);
    }
    int main()
    {
        int n,T,l,r;
        scanf("%d%d",&n,&T);
        root=ins(0,n+1);
        while(T--)
        {
            scanf("%d%d",&l,&r);l++;r++;
            fanzhuan(l,r);
        }
        alen=0;dfs(root);
        for(int i=2;i<alen-1;i++)printf("%d ",a[i]);
        printf("%d",a[alen-1]);
        return 0;
    }

     

  • 相关阅读:
    集合set() 和 深浅copy
    Python 数据类型的操作——字典
    Python()- 面向对象
    面向对象的软件开发
    Python数据类型的操作——列表、元组
    Python 数据类型的操作——字符串
    Linux下386中断处理
    任务的休眠与唤醒
    Linux下SIGSTOP的特殊特征和实现
    内核线程对信号的处理策略
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8082361.html
Copyright © 2011-2022 走看看