題目連結: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 }
View Code
轉載于:https://www.cnblogs.com/bin-gege/p/6346908.html