首页 > 代码库 > hdu 3487 Play with Chain(splay区间剪切,翻转)
hdu 3487 Play with Chain(splay区间剪切,翻转)
题目链接:hdu 3487 Play with Chain
题意:
cut a b c:
将a到b区间剪切下来,放在第c位置的后面。
flip a b:
翻转a到b区间
题解:
第一个操作,选通过旋转,然后使a到b区间变成根的右儿子的左儿子,然后剪掉。
再找到c+1的位置,接上。
第二个操作,区间标记就行。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 const int N=1e6+7; 5 int _t; 6 7 struct Splay_tree 8 { 9 int root,q[N];bool rev[N]; 10 int key[N],sz[N],f[N],ch[N][2]; 11 void rev1(int x){if(x)swap(ch[x][0],ch[x][1]),rev[x]^=1;} 12 inline void nw(int &x,int val,int fa) 13 { 14 x=++_t,key[x]=val,f[x]=fa,sz[x]=1; 15 ch[x][0]=ch[x][1]=0; 16 rev[x]=0; 17 } 18 inline void pd(int x){if(rev[x])rev1(ch[x][0]),rev1(ch[x][1]),rev[x]=0;} 19 inline void up(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;} 20 void rotate(int x){ 21 int y=f[x],w=ch[y][1]==x; 22 ch[y][w]=ch[x][w^1]; 23 if(ch[x][w^1])f[ch[x][w^1]]=y; 24 if(f[y]){ 25 int z=f[y]; 26 if(ch[z][0]==y)ch[z][0]=x; 27 if(ch[z][1]==y)ch[z][1]=x; 28 } 29 f[x]=f[y],ch[x][w^1]=y,f[y]=x,up(y); 30 } 31 void splay(int x,int w){ 32 int s=1,i=x,y;q[1]=x; 33 while(f[i])q[++s]=i=f[i]; 34 while(s)pd(q[s--]); 35 while(f[x]!=w){ 36 y=f[x]; 37 if(f[y]!=w){if((ch[f[y]][0]==y)^(ch[y][0]==x))rotate(x);else rotate(y);} 38 rotate(x); 39 } 40 if(!w)root=x; 41 up(x); 42 } 43 void build(int &x,int l,int r,int fa=0)//按照数组下标建树 44 { 45 if(l>r)return; 46 int mid=l+r>>1; 47 nw(x,mid,fa); 48 build(ch[x][0],l,mid-1,x); 49 build(ch[x][1],mid+1,r,x); 50 up(x); 51 } 52 inline int kth(int k)//获得第k小 53 { 54 if(k>sz[root]||k<=0)return 0; 55 int x=root,tmp; 56 while(1) 57 { 58 pd(x),tmp=sz[ch[x][0]]+1; 59 if(k==tmp)break; 60 if(k<tmp)x=ch[x][0];else k-=tmp,x=ch[x][1]; 61 } 62 return x; 63 } 64 void reverse(int a,int b)//翻转a到b区间 65 { 66 splay(kth(a),0),splay(kth(b+2),root); 67 rev1(ch[ch[root][1]][0]); 68 } 69 void cut(int a,int b,int c) 70 { 71 splay(kth(a),0),splay(kth(b+2),root); 72 int tmp=ch[ch[root][1]][0]; 73 ch[ch[root][1]][0]=0; 74 pd(ch[root][1]),pd(root); 75 splay(kth(c+1),0); 76 splay(kth(c+2),root); 77 ch[ch[root][1]][0]=tmp; 78 f[ch[ch[root][1]][0]]=ch[root][1]; 79 up(ch[root][1]),up(root); 80 } 81 }spt; 82 //-------------------------------- 83 84 int n,m,cnt; 85 86 void out(int x) 87 { 88 if(!x)return; 89 spt.pd(x),out(spt.ch[x][0]); 90 if(spt.key[x]>1&&spt.key[x]<n+2)printf("%d%c",spt.key[x]-1," \n"[++cnt==n]); 91 out(spt.ch[x][1]); 92 } 93 94 int main() 95 { 96 while(~scanf("%d%d",&n,&m)) 97 { 98 if(n==-1)break; 99 _t=0,spt.build(spt.root,1,n+2); 100 char cmd[10]; 101 int a,b,c; 102 F(i,1,m) 103 { 104 scanf("%s",cmd); 105 if(cmd[0]==‘C‘) 106 { 107 scanf("%d%d%d",&a,&b,&c); 108 spt.cut(a,b,c); 109 }else scanf("%d%d",&a,&b),spt.reverse(a,b); 110 } 111 cnt=0,out(spt.root); 112 } 113 return 0; 114 }
hdu 3487 Play with Chain(splay区间剪切,翻转)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。