hdu 4286 Data Handler(Splay)

题意:给你一串数字,左右指针的位置,有五种操作,左右指针的左移右移,删除左指针右边的数,删除右指针左边的数,翻转两个指针之间的数。

Splay搞过去了。。T了几发是因为,删除的时候,可以把要删除的那个点转到根结点,删除根结点,合并两个子树,然后这样就T了,换了个姿势就过了。。C++扩栈不解释。。

#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

#define LL(x) (ch[x][0])
#define RR(x) (ch[x][1])
#define MID(a,b) (a+((b-a)>>1))
#define Kt ( ch[ ch[Rt][1] ][0] )

const int N=1000005;

int n,m;
int a[N/2],cnt;
int posL,posR;
int ans[N];

struct SplayTree
{
    int Rt,top;
    int pre[N],sz[N],ch[N][2];

    int key[N];
    bool flip[N];

    inline void Link(int x,int y,int f)
    {
        pre[x]=y; if(y!=0) ch[y][f]=x;
    }
    inline void Rotate(int x,int f)
    {
        int y=pre[x],z=pre[y];

        PushDown(y); PushDown(x);

        Link(x,z,RR(z)==y);
        Link(ch[x][f],y,!f);
        Link(y,x,f);

        PushUp(y);
    }
    inline void Splay(int x,int goal)
    {
        while(pre[x]!=goal)
        {
            int y=pre[x],z=pre[y];
            int cx=(LL(y)==x),cy=(LL(z)==y);
            if(z==goal) Rotate(x,cx);
            else
            {
                if(cx==cy) Rotate(y,cy);
                else Rotate(x,cx);
                Rotate(x,cy);
            }
        }
        PushUp(x);
        if(goal==0) Rt=x;
    }
    inline void Select(int K,int goal)
    {
        int x=Rt;
        PushDown(x);
        while(1)
        {
            if(sz[LL(x)]>=K) x=LL(x);
            else if(sz[LL(x)]+1==K) break;
            else K-=sz[LL(x)]+1,x=RR(x);
            PushDown(x);
        }
        Splay(x,goal);
    }
    inline void Insert(int pos,int valu)
    {
        Select(pos,0);
        Select(pos+1,Rt);

        addNode(valu,Kt,RR(Rt));
        PushUp(RR(Rt)); PushUp(Rt);
    }
    inline void Delete(int pos)
    {
        if(pos==1||pos==sz[Rt]) return;

        Select(pos-1,0);
        Select(pos+1,Rt);
        LL(RR(Rt))=0;
        PushUp(RR(Rt)); PushUp(Rt);
    }

    inline void iswap(int x)
    {
        if(x==0) return;
        flip[x]^=1;
        swap(LL(x),RR(x));
    }
    inline void Flip(int st,int ed)
    {
        Select(st-1,0);
        Select(ed+1,Rt);

        iswap(Kt);
    }
    inline void PushDown(int x)
    {
        if(flip[x])
        {
            iswap(LL(x)); iswap(RR(x));
            flip[x]=0;
        }
    }
    inline void PushUp(int x)
    {
        sz[x]=1+sz[LL(x)]+sz[RR(x)];
    }
    inline void addNode(int valu,int &x,int f)
    {
        x=++top;
        pre[x]=f; LL(x)=RR(x)=0; sz[x]=1;

        key[x]=valu; flip[x]=0;
    }
    void build(int lft,int rht,int &x,int fa)
    {
        if(lft>rht) return;

        int mid=MID(lft,rht);

        addNode(a[mid],x,fa);

        build(lft,mid-1,LL(x),x);
        build(mid+1,rht,RR(x),x);

        PushUp(x);
    }
    void init()
    {
        Rt=top=0;
        sz[0]=pre[0]=LL(0)=RR(0)=flip[0]=0;

        addNode(0,Rt,0);
        addNode(0,RR(Rt),Rt);

        build(0,n-1,Kt,RR(Rt));
        PushUp(RR(Rt)); PushUp(Rt);
    }

    void Debug() { printf("Rt:%d\n",Rt); Travel(Rt,0); }
    void Travel(int x,bool flag)
    {
        if(x==0) return;
        PushDown(x);
        Travel(LL(x),flag);
        if(flag==0) printf("node:%d,pre:%d,lSon:%d,rSon:%d,sz:%d,key:%d\n",x,pre[x],LL(x),RR(x),sz[x],key[x]);
       if(cnt>=1&&cnt<sz[Rt]-1)
       {
            if(cnt==1) printf("%d",key[x]);
            else printf(" %d",key[x]);

       }
        cnt++;
        Travel(RR(x),flag);
    }

}spt;
int main()
{
    freopen("in.txt","r",stdin);

    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        scanf("%d%d",&posL,&posR);
        posR+=2;

        spt.init();

        int valu;
        char op1[100],op2[100];

        scanf("%d",&m);
        while(m--)
        {
            scanf("%s",op1);
            int len=spt.sz[spt.Rt];
            if(op1[0]=='M')
            {
                scanf("%s",op2);
                if(op1[4]=='L')
                {
                    if(op2[0]=='L') posL-=(posL>1);
                    else posR-=(posR>1);
                }
                else
                {
                    if(op2[0]=='L') posL+=(posL<len);
                    else posR+=(posR<len);
                }
            }
            else if(op1[0]=='I')
            {
                scanf("%s%d",op2,&valu);

                if(op2[0]=='L') spt.Insert(posL,valu);
                else spt.Insert(posR-1,valu);
                posR++;
            }
            else if(op1[0]=='D')
            {
                scanf("%s",op2);
                if(op2[0]=='L') spt.Delete(posL+1);
                else spt.Delete(posR-1);
                posR--;
            }
            else
            {
                spt.Flip(posL+1,posR-1);
            }
        }
        cnt=0;
        spt.Travel(spt.Rt,1);
        puts("");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/shiqi_614/article/details/10953603