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

 

posted @ 2017-12-21 20:36  Star_Feel  阅读(183)  评论(0编辑  收藏  举报