splay

来源:互联网 发布:广联达电气预算软件 编辑:程序博客网 时间:2024/04/26 10:39
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 300100;int aa[N];struct Node{    Node *ch[2],*pre;    int sz,fg;    int val;}node[N];int n_cnt;Node *null;void init(){    null=&node[0];null->ch[0]=null->ch[1]=null->pre=null;    null->fg=null->sz=0;    null->val=0;    n_cnt=1;}int ans[N],top;struct SPT{    Node* root;    inline void pushup(Node* x){        Node *u1=x->ch[0],*u2=x->ch[1];        x->sz=u1->sz+u2->sz+1;    }    inline void pushdown(Node * x){        Node* u1=x->ch[0],*u2=x->ch[1];        if(x->fg)        {            swap(x->ch[0],x->ch[1]);            x->fg=0;            if(u1!=null)u1->fg^=1;            if(u2!=null)u2->fg^=1;        }//        if(x->add)//        {//            if(u1!=null)//            {//                u1->add+=x->add;//                u1->val+=x->add;//                u1->sum+=u1->sz*x->add;//            }//            if(u2!=null)//            {//                u2->add+=x->add;//                u2->val+=x->add;//                u2->sum+=(LL)u2->sz*x->add;//            }//            x->add=0;//        }    }inline void rotate(Node* x,int f) {        Node *y=x->pre;        pushdown(y);        pushdown(x);        y->ch[!f]=x->ch[f];        if(x->ch[f]!=null)x->ch[f]->pre=y;        x->pre=y->pre;        if(y->pre!=null)        {            y->pre->ch[y->pre->ch[1]==y]=x;        }        x->ch[f]=y;        y->pre=x;        pushup(y);}inline void splay(Node *x,Node *g) {        pushdown(x);        while(x->pre!=g)        {            if(x->pre->pre==g)            {                rotate(x,x->pre->ch[0]==x);            }            else            {                Node *y=x->pre,*z=y->pre;                int f=z->ch[0]==y;                if(y->ch[f]==x)                {                    rotate(x,!f);rotate(x,f);                }                else                {                    rotate(y,f);rotate(x,f);                }            }        }        pushup(x);        if(g==null)root=x;}    inline void select(int k,Node *f) {    // 把第k个点旋转到f的下面        Node* x = root;        Node *u1,*u2;        while ( 1 ) {            pushdown(x);            u1=x->ch[0],u2=x->ch[1];            if ( k == u1->sz + 1 )                break;            if ( k <= u1->sz )                x = u1;            else {                k -= u1->sz+1;                x = u2;            }        }        splay(x, f);    }    inline void del_root(){//删除根节点        Node* t=root;        if(root->ch[1]!=null) {            select(root->ch[0]->sz+2,root);//把右子树中序遍历的第一个点旋转到根(因为这个点的左儿子肯定为空)            root=root->ch[1];            root->ch[0]=t->ch[0];//将原先根节点的左子树接到当前根节点的左子树上            if(t->ch[0]!=null) t->ch[0]->pre=root;        }        else            root=root->ch[0];        root->pre=null;        pushup(root);    }    void split(Node* o,int k,Node* &left,Node* &right)    {        root=o;        select(k,null);        right=root->ch[1];        right->pre=null;        root->ch[1]=null;        pushup(root);        left=root;    }    void merge(Node* &left,Node* right)    {        root=left;        select(root->sz,null);        root->ch[1]=right;        right->pre=root;        pushup(root);        left=root;    }    void dfs(Node* x)    {        if(x==null)return ;        pushdown(x);        dfs(x->ch[0]);        //printf("%d ",x->val);        ans[top++]=x->val;        dfs(x->ch[1]);    }    void build(Node* &x,int l,int r)    {        if(l>r)return ;        x=&node[n_cnt++];        int mid=(l+r)/2;        x->ch[0]=x->ch[1]=null;        x->val=aa[mid];        x->fg=0;        build(x->ch[0],l,mid-1);        build(x->ch[1],mid+1,r);        Node *u1=x->ch[0],*u2=x->ch[1];        if(u1!=null)u1->pre=x;        if(u2!=null)u2->pre=x;        pushup(x);    }}spt;int n,m;char ss[10];Node* Root,*Left,*Right,*Mid;int main(){    freopen("C:\\Users\\Administrator\\Desktop\\aa.txt","r",stdin);    freopen("C:\\Users\\Administrator\\Desktop\\dd.txt","w",stdout);    while(scanf("%d%d",&n,&m),n>=0&&m>=0)    {        init();        for(int i=1;i<=n;i++)        {            aa[i]=i;        }        aa[0]=aa[n+1]=0;        spt.build(Root,0,n+1);        Root->pre=null;        //printf("build\n");        for(int i=1;i<=m;i++)        {            scanf("%s",ss);            if(ss[0]=='C')            {                int a,b,c;scanf("%d%d%d",&a,&b,&c);a++;b++;c++;                spt.split(Root,a-1,Left,Mid);                Root=Mid;                spt.split(Root,b-a+1,Mid,Right);                Root=Left;                spt.merge(Root,Right);                spt.split(Root,c,Left,Right);                Root=Left;                spt.merge(Root,Mid);                spt.merge(Root,Right);            }            else            {                int a,b;scanf("%d%d",&a,&b);a++;b++;                spt.root=Root;                spt.select(a-1,null);                Root=spt.root;                spt.root=Root;                spt.select(b+1,Root);                Root=spt.root;                Root->ch[1]->ch[0]->fg^=1;            }        }        top=0;        spt.dfs(Root);        for(int i=1;i<top-1;i++)        {            if(i>1)printf(" ");            printf("%d",ans[i]);        }printf("\n");    }    return 0;}

0 0
原创粉丝点击