小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。
第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。
对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。
1 #include <algorithm>
2 #include <iostream>
3 #include <cstdlib>
4 #include <cstring>
5 #include <cstdio>
6 #include <cmath>
7 #define maxn 200010
8 using namespace std;
9 int ch[maxn][2],pre[maxn],size[maxn],key[maxn],id[maxn],tot=0,root=1;
10 char s[10];
11 inline void Rotate(int x,int kind){
12 int y=pre[x];
13 ch[y][!kind]=ch[x][kind];
14 pre[ch[x][kind]]=y;
15 if(pre[y])
16 ch[pre[y]][ch[pre[y]][1]==y]=x;
17 pre[x]=pre[y];
18 ch[x][kind]=y;
19 pre[y]=x;
20 size[y]=size[ch[y][0]]+size[ch[y][1]]+1;
21 size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
22 }
23 inline void splay(int r,int goal){
24 while(pre[r]!=goal){
25 if(pre[pre[r]]==goal)
26 Rotate(r,ch[pre[r]][0]==r);
27 else{
28 int y=pre[r];
29 int kind=ch[pre[y]][0]==y;
30 if(ch[y][kind]==r){
31 Rotate(r,!kind);
32 Rotate(r,kind);
33 }
34 else{
35 Rotate(y,kind);
36 Rotate(r,kind);
37 }
38 }
39 }
40 if(goal==0) root=r;
41 }
42 void newnode(int &x,int fa,int keyy){
43 x=++tot;
44 pre[x]=fa;
45 size[x]=1;
46 key[x]=keyy;
47 }
48 void query(int x){
49 int rt=root;
50 while(x){
51 if(size[ch[rt][0]]+1==x) break;
52 if(size[ch[rt][0]]+1<x) x-=(size[ch[rt][0]]+1),rt=ch[rt][1];
53 else rt=ch[rt][0];
54 }
55 printf("%d\n",key[rt]);
56 }
57 void top(int x){
58 int kt=id[x];
59 splay(kt,0);
60 if(!ch[kt][0]) return;
61 int p1=ch[kt][0];
62 while(ch[p1][1]) p1=ch[p1][1];
63 splay(p1,root);
64 if(!ch[kt][1]) root=ch[kt][0],pre[ch[kt][0]]=0;
65 else{
66 int p2=ch[kt][1];
67 while(ch[p2][0]) p2=ch[p2][0];
68 splay(p2,root);
69 pre[p1]=0;
70 pre[p2]=p1;
71 ch[p1][1]=p2;
72 root=p1;
73 }
74 int rt=p1;
75 while(ch[rt][0]) rt=ch[rt][0];
76 splay(rt,0);
77 newnode(ch[root][0],root,x);
78 size[root]=size[ch[root][0]]+size[ch[root][1]]+1;
79 id[x]=ch[root][0];
80 }
81 void bottom(int x){
82 int kt=id[x];
83 splay(kt,0);
84 if(!ch[kt][1]) return;
85 int p1=ch[kt][1];
86 while(ch[p1][0])
87 p1=ch[p1][0];
88 splay(p1,root);
89 if(!ch[kt][0]) root=ch[kt][1],pre[ch[kt][1]]=0;
90 else{
91 int p2=ch[kt][0];
92 while(ch[p2][1]) p2=ch[p2][1];
93 splay(p2,root);
94 pre[p1]=0;
95 pre[p2]=p1;
96 ch[p1][0]=p2;
97 root=p1;
98 }
99 int rt=p1;
100 while(ch[rt][1]) rt=ch[rt][1];
101 splay(rt,0);
102 newnode(ch[root][1],root,x);
103 size[root]=size[ch[root][0]]+size[ch[root][1]]+1;
104 id[x]=ch[root][1];
105 }
106 void Insert(int x){
107 int k;
108 scanf("%d",&k);
109 if(k==0) return;
110 splay(id[x],0);
111 if(k==1){
112 int rt=ch[root][1];
113 if(rt==0) return;
114 while(ch[rt][0]) rt=ch[rt][0];
115 splay(rt,root);
116 pre[ch[root][1]]=0;
117 pre[ch[root][0]]=ch[root][1];
118 ch[ch[root][1]][0]=ch[root][0];
119 root=ch[root][1];
120 rt=ch[root][1];
121 size[root]++;
122 if(rt==0) newnode(ch[root][1],root,x),id[x]=ch[root][1];
123 else{
124 while(ch[rt][0]) size[rt]++,rt=ch[rt][0];
125 size[rt]++;
126 newnode(ch[rt][0],rt,x);
127 id[x]=ch[rt][0];
128 }
129 }
130 else{
131 int rt=ch[root][0];
132 if(rt==0) return;
133 while(ch[rt][1]) rt=ch[rt][1];
134 splay(rt,root);
135 pre[ch[root][0]]=0;
136 pre[ch[root][1]]=ch[root][0];
137 ch[ch[root][0]][1]=ch[root][1];
138 root=ch[root][0];
139 rt=ch[root][0];
140 size[root]++;
141 if(rt==0) newnode(ch[root][0],root,x),id[x]=ch[root][0];
142 else{
143 while(ch[rt][1]) size[rt]++,rt=ch[rt][1];
144 size[rt]++;
145 newnode(ch[rt][1],rt,x);
146 id[x]=ch[rt][1];
147 }
148 }
149 }
150 void ask(int x){
151 int k=id[x];
152 splay(k,0);
153 printf("%d\n",size[ch[k][0]]);
154 }
155 int main()
156 {
157 int n,m,x;
158 scanf("%d%d",&n,&m);
159 scanf("%d",&x);
160 id[x]=1;pre[1]=0;
161 key[1]=x;
162 size[1]=n;
163 for(int i=2;i<=n;i++){
164 scanf("%d",&x);
165 ch[i-1][1]=i;
166 pre[i]=i-1;
167 size[i]=n-i+1;
168 id[x]=i;
169 key[i]=x;
170 }
171 if(n>2)
172 splay(n/2,0);
173 tot=n;
174 for(int i=1;i<=m;i++){
175 scanf("%s%d",s,&x);
176 if(s[0]==‘Q‘) query(x);
177 if(s[0]==‘T‘) top(x);
178 if(s[0]==‘B‘) bottom(x);
179 if(s[0]==‘I‘) Insert(x);
180 if(s[0]==‘A‘) ask(x);
181 }
182 return 0;
183 }