hdu3487 Splay

来源:互联网 发布:淘宝白色长连衣裙 编辑:程序博客网 时间:2024/06/05 17:30

题意:给定数字的序列 操作是翻转序列中的一段数字 或者是 将其中一段数字剪切下来 然后粘贴在剪切完的数组的一个数之后

解法:splay区间翻转,区间剪切

这个旋转操作ms有点花样的

#include<cstdio>#include<iostream>using namespace std;#define maxn 333333#define rls ch[root][0]#define rrs ch[root][1]#define ls ch[rt][0]#define rs ch[rt][1]int ch[maxn][2],num[maxn],fa[maxn],rev[maxn];int n,m,root,cnt;void up(int rt){    num[rt]=num[ls]+num[rs]+1;}void down(int rt){    swap(ls,rs);    rev[ls]^=1;rev[rs]^=1;    rev[rt]=0;}void build(){    memset(ch,0,sizeof ch);    memset(rev,0,sizeof rev);    for(int i=1;i<=n+2;++i)        fa[i]=i+1,num[i]=i,ch[i][0]=i-1;    root=n+2;fa[n+2]=0;    cnt=0;}void rot(int rt){    int f=fa[rt],side=(ch[f][1]==rt),&ll=ch[rt][!side];    fa[ll]=f;ch[f][side]=ll;    fa[rt]=fa[f];ch[fa[f]][ch[fa[f]][1]==f]=rt;    fa[f]=rt,ch[rt][!side]=f;    up(f),up(rt);}void splay(int rt,int aim){    while(fa[rt]!=aim){        int f=fa[rt],ff=fa[f];        if(ff==aim)rot(rt);        else if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt);        else rot(rt),rot(rt);    }if(!aim)root=rt;}void find(int tot,int sub){    int rt=sub;    while(1){        if(rev[rt])down(rt);        if(num[ls]==tot-1)break;        if(num[ls]>=tot)rt=ls;        else tot-=num[ls]+1,rt=rs;    }    splay(rt,fa[sub]);}void flip(int l,int r){    find(l,root);    find(r-l+2,rrs);    rev[ch[rrs][0]]^=1;}void cut(int l,int r,int pos){    find(l,root);    find(r-l+2,rrs);    int rl=ch[rrs][0];    ch[rrs][0]=0;up(rrs),up(root);    find(pos+2,root);    find(pos+1,rls);    ch[rls][1]=rl;fa[rl]=rls;    up(rls),up(root);}int ans[maxn];void print(int rt){    if(rev[rt])down(rt);    if(ls)print(ls);    ans[++cnt]=rt;    if(rs)print(rs);}int a,b,c;int main(){    while(~scanf("%d%d",&n,&m)){        if(n==-1&&m==-1)break;        build();        char s[111];        while(m--){            scanf("%s",s);            if(*s=='F'){                scanf("%d%d",&a,&b);                flip(a,b);            }else if(*s=='C'){                scanf("%d%d%d",&a,&b,&c);                cut(a,b,c);            }        }        print(root);        for(int i=2;i<cnt;++i)printf(i==2?"%d":" %d",ans[i]-1);        printf("\n");    }    return 0;}



0 0