题意:给出n和q,n代表1-n的序列,接下来q有两种操作,Cut a b c:表示把区间[a,b]截掉然后放在第c个数的后面,Flip a b 表示把区间[a,b]反转,经过一系列的q操作,最后输出操作后的序列:

分析:首先建立初始化的树结构之前,先给n设置个极限范围0和n+1,防止特殊情况下越界,如果反转[a,b],则先把第a-1个数放在根节点,把b+1结点的数放在根节点的右儿子下面,此时根节点的右儿子的左儿子为根的子树就是[a,b]区间,然后把反转标记传递给该子树的根节点,如果剪切区间[a,b]则把第c+1个数旋转到根节点处,然后把根节点的右儿子为子树的最左面的节点旋转到该子树的根,此时把剪掉的子树的根节点连到根节点的右儿子的左儿子上面即可,需要注意的是,push_down和push_up的操作

codes:指针

#include"stdio.h"
#include"iostream"
#include"queue"
using namespace std;
struct Link_cut
{

    queue<int>q;
    struct node     //节点结构体
    {
        int key,val,son,flag;
        node *lson,*rson,*fa;  //左儿子,右儿子,以及父节点
        node()
        {
            key=val=flag=0;
            son=1;
            lson=rson=fa=NULL;
        }
    };
    node *top,*root,*x,*y;
    void init() //建立根节点root的父节点top
    {
        top=new node();
    }
    int getNum(node *x) //以x为根的子树一共有多少个节点
    {
        if(x==NULL)return 0;
        return x->son;
    }
    void push_up(node *rt)
    {
        rt->son=getNum(rt->lson)+getNum(rt->rson)+1;
    }
    void push_down(node *rt)
    {
        if(rt==NULL)return;
        if(rt->flag)
        {
            rt->flag^=1;
            Reversal(rt);
            if(rt->lson!=NULL)
            rt->lson->flag^=1;
            if(rt->rson!=NULL)
            rt->rson->flag^=1;
        }
    }
    void Rotate(node *x,int k)  //k=0左旋k=1右旋
    {
        node *y=x->fa;
        if(k==0)
        {
            y->rson=x->lson;
            if(y->rson!=NULL)
                y->rson->fa=y;

            push_up(y);
            if(y->fa->rson==y)
                y->fa->rson=x;
            else
                y->fa->lson=x;
            x->fa=y->fa;

            x->lson=y;
            y->fa=x;
        }
        else
        {
            y->lson=x->rson;
            if(y->lson!=NULL)
                y->lson->fa=y;

            push_up(y);
            if(y->fa->lson==y)
                y->fa->lson=x;
            else
                y->fa->rson=x;
            x->fa=y->fa;

            x->rson=y;
            y->fa=x;
        }
    }
    void Splay(node *x,node *f)//把x旋转到f的下面
    {
        while(x->fa!=f)
        {
            node *y=x->fa;
            node *z=y->fa;
            if(z==f)
            {
                if(y->rson==x)
                    Rotate(x,0);
                else
                    Rotate(x,1);
            }
            else
            {
                if(z->rson==y)
                {
                    if(y->rson==x)
                    {
                        Rotate(y,0);
                        Rotate(x,0);
                    }
                    else
                    {
                        Rotate(x,1);
                        Rotate(x,0);
                    }
                }
                else
                {
                    if(y->lson==x)
                    {
                        Rotate(y,1);
                        Rotate(x,1);
                    }
                    else
                    {
                        Rotate(x,0);
                        Rotate(x,1);
                    }
                }
            }
        }
        if(f==top)
            root=x;
    }
    void RotateTo(node *x,node *f)
    {
        Splay(x,f);
        push_up(x);
    }
    void RotateTo(int k,node *f)
    {
        node *x=root;
        k++;
        while(1)
        {
            push_down(x);
            int temp=getNum(x->lson)+1;
            if(k==temp)break;
            if(k<temp)
                x=x->lson;
            else
            {
                k-=temp;
                x=x->rson;
            }
        }
        Splay(x,f);
        push_up(x);
    }
    void creatTree(int l,int r,int k,node *f) //初始化一颗二叉树
    {
        if(l>r)return;
        int mid=(l+r)/2;
        node *rt=new node();
        if(f==top)
            root=rt;
        if(k==0)
        {
            f->lson=rt;
            rt->fa=f;
            rt->key=mid;
        }
        else
        {
            f->rson=rt;
            rt->fa=f;
            rt->key=mid;
        }
        creatTree(l,mid-1,0,rt);
        creatTree(mid+1,r,1,rt);
        push_up(rt);
    }
    void Reversal(node *x)//交换x左右儿子的结点
    {
        if(x==NULL)return;
        node *y=x->lson;
        x->lson=x->rson;
        x->rson=y;
    }
    node *Find(int k) //找到第k的结点
    {
        node *x=root;
        k++;
        while(1)
        {
            push_down(x);
            int temp=getNum(x->lson)+1;
            if(k==temp)break;
            else if(k<temp)
                x=x->lson;
            else
            {
                k-=temp;
                x=x->rson;
            }
        }
        return x;
    }
    node *FindRight(node *rt) //找到以rt为根节点的最右一个结点
    {
        node *x=rt;
        while(1)
        {
            push_down(x);
            if(x->rson==NULL)
                break;
            x=x->rson;
        }
        return x;
    }
    node *FindLeft(node *rt)  //找到以rt为根节点的最左一个结点
    {
        node *x=rt;
        while(1)
        {
            push_down(x);
            if(x->lson==NULL)break;
            x=x->lson;
        }
        return x;
    }
    void Link(node *rt,int k) //把rt为根的子树连接到第k个结点的后面
    {
        root->rson->lson=NULL; //把区间砍掉
        node *x=Find(k);
        RotateTo(x,top);
        node *y=FindLeft(root->rson);
        RotateTo(y,root);

        root->rson->lson=rt;
        rt->fa=root->rson;
    }
    void Output(node *x,int n)
    {
        if(x==NULL)return;
        push_down(x);
        Output(x->lson,n);
        if(x->key>=1&&x->key<=n)
        q.push(x->key);
        Output(x->rson,n);
    }
}h;
int main()
{
    int n,q;
    while(scanf("%d%d",&n,&q)!=-1)
    {
        if(n==-1&&q==-1)break;
        h.init();
        h.creatTree(0,n+1,0,h.top);
        char op[11];
        int a,b,c;

        while(q--)
        {

            scanf("%s%d%d",op,&a,&b);
            if(op[0]=='C')
            {
                scanf("%d",&c);
                h.RotateTo(a-1,h.top);
                h.RotateTo(b+1,h.root);
                h.Link(h.root->rson->lson,c);
            }
            else
            {
                h.RotateTo(a-1,h.top);
                h.RotateTo(b+1,h.root);
                h.root->rson->lson->flag^=1;
            }
        }
        while(!h.q.empty())
        {
            h.q.pop();
        }
        h.Output(h.root,n);
        printf("%d",h.q.front());
        h.q.pop();
        while(!h.q.empty())
        {
            printf(" %d",h.q.front());
            h.q.pop();
        }
        puts("");

    }
}
/*
8 1
CUT 3 5 4

5 1
CUT 2 3 1

8 3
Cut 3 6 3
Cut 2 6 2
Cut 3 6 4

8 1
Flip 2 6

10 5
Cut 2 6 3
Flip 4 9
Flip 5 8
Cut 6 7 3
Flip 4 5
*/
View Code

相关文章: